diff --git a/app/by_frame.c b/app/by_frame.c index bed8a72..8a0cac9 100644 --- a/app/by_frame.c +++ b/app/by_frame.c @@ -7,14 +7,14 @@ #include "lwrb.h" #include "crc16.h" -uint8_t frame_buffer_recv[(2 * (4 + 8))]; +uint8_t frame_buffer_recv[(2 * (4 + 8)) + 1]; uint8_t frame_buffer_send[4 + 8]; uint8_t frame_parse_busy; -fifo_struct frame_fifo; +lwrb_t lwrb_ctx; void by_frame_init(void) { - fifo_init(&frame_fifo, FIFO_DATA_8BIT, frame_buffer_recv, (2 * (4 + 8))); + lwrb_init(&lwrb_ctx, frame_buffer_recv, sizeof(frame_buffer_recv)); // lwrb 最大元素数量为 buff 大小减一 uart_init(BY_FRAME_UART_INDEX, BY_FRAME_UART_BAUDRATE, BY_FRAME_UART_TX_PIN, BY_FRAME_UART_RX_PIN); uart_rx_interrupt(BY_FRAME_UART_INDEX, ENABLE); } @@ -34,15 +34,20 @@ void by_frame_send(uint8_t data_num, uint32_t *data_array) uart_write_buffer(BY_FRAME_UART_INDEX, frame_buffer_send, 4 + data_num * sizeof(uint32_t)); } +/** + * @brief + * + * @param data_num + * @param data_array + * @todo 将其中写死的数据长度按照宏定义给出 + */ void by_frame_parse(uint8_t data_num, uint32_t *data_array) { - - uint16_t len = (uint16_t)fifo_used(&frame_fifo); - uint16_t len_cnt = len; - uint8_t status = 0; - uint16_t frame_start = 0; - uint8_t frame_buffer[4 + 8] = {0}; - uint8_t buf[sizeof(frame_buffer)] = {0}; + uint32_t len = lwrb_get_full(&lwrb_ctx); // 缓冲区大小 + uint8_t status = 0; // 状态 0-未找到帧头 1-找到帧头 2-校验 + uint16_t frame_start = 0; // 帧起始位置 + uint8_t frame_buf[4 + 8] = {0}; // 帧 + uint8_t buf[(4 + 8) * 2] = {0}; // 用于解析的数据块 if (len < 2 * (4 + 4 * data_num)) { // 当前要求缓冲区满 @@ -55,39 +60,50 @@ void by_frame_parse(uint8_t data_num, uint32_t *data_array) // 目前的解决办法大概是缓冲区开两帧长的大小,然后一次性读完 // 读取的时候不清除,等待新帧覆盖 + // 用 lwrb 的话就只能清除了 return; } - fifo_read_buffer(&frame_fifo, buf, &len, FIFO_READ_ONLY); + // 从环形缓冲区里读取数据 + lwrb_read(&lwrb_ctx, buf, len); - while (len_cnt--) { + // 递归解析有效帧 + while (1) { if (0 == status) // 没找到帧头 { - printf("finding frame head, now frame_start %d\r\n", frame_start); - uint16_t temp = *((uint16_t *)(buf + (frame_start++))); - printf("now find %02X\r\n", temp); + // 读到最后一个元素还没找到帧头 + if (frame_start >= len - 2) { + return; + } + // printf("finding frame head, now frame_start %d\r\n", frame_start); + uint16_t temp = (buf[frame_start] | (buf[frame_start + 1] << 8)); + frame_start++; + // printf("now find %02X\r\n", temp); // 递归寻找帧头,直接俩拼起来找 注意比较的时候低位在前 if ((BY_FRAME_HEAD_2 << 8 | BY_FRAME_HEAD_1) == temp) { status = 1; // 找到了好耶 - printf("frame head found!!!!!!!!!\r\n"); + // printf("frame head found!!!!!!!!!\r\n"); } continue; } - if (1 == status) // 开始读数据 - { - if ((frame_start + 4 + 8) >= len) // 剩下的数据不够组成一帧 - { - printf("failed! length not enough \r\n"); - return; // 解析出错,缓冲区中没有有效帧 + // 开始读数据 + if (1 == status) { + // 剩下的数据不够组成一帧 + if ((frame_start + 4 + 8 - 1) > len) { + // printf("failed! length not enough \r\n"); + // 解析出错,缓冲区中没有有效帧 + return; } else { - memcpy(frame_buffer, buf + frame_start - 1, 4 + 8); // 复制到帧缓冲区,减一是因为之前多加了一次 - for (uint8_t i = 0; i < 12; i++) { - printf("%02X", frame_buffer[i]); - } + // 复制到帧缓冲区,减一是因为之前多加了一次 + memcpy(frame_buf, buf + frame_start - 1, 4 + 8); + + // for (uint8_t i = 0; i < 12; i++) { + // printf("%02X", frame_buf[i]); + // } + // printf("\r\n"); - printf("\r\n"); status = 2; } continue; @@ -95,86 +111,30 @@ void by_frame_parse(uint8_t data_num, uint32_t *data_array) if (2 == status) // 校验 CRC { - // TODO 确认一下高低位 - if (*((uint16_t *)(frame_buffer + 2 + 8)) == crc16_check(frame_buffer, 2 + 4 * data_num)) // 暂时用 0xFF 替代 注意比较的时候字节序!!! - { - printf("parsed done!!!!!!!!\r\n"); // 解析成功了✌ - memcpy(data_array, frame_buffer + 2, 4 * data_num); // 复制数据 + if ((frame_buf[2 + 8] << 8 | frame_buf[2 + 8 + 1]) == crc16_check(frame_buf, 2 + 4 * data_num)) { + // 解析成功了✌ + // printf("parsed done!!!!!!!!\r\n"); + // 复制数据 + memcpy(data_array, frame_buf + 2, 4 * data_num); return; } else { status = 0; - // frame_start += (8 - 1); // 这样无法应对连续帧之间缺字节的的问题,但是减少了重新遍历寻找帧头的时间 - frame_start += (2 - 1); // 从上一个帧头之后开始解析 + // 这样无法应对连续帧之间缺字节的的问题,但是减少了重新遍历寻找帧头的时间 + // frame_start += (8 - 1); + // 从上一个帧头之后开始解析 + frame_start += (2 - 1); continue; } } } return; - - // uint8_t cnt = 0; - // uint8_t cnt_crc = 2; - // uint8_t cnt_ptr = 0; - // uint8_t data = 0; - // uint8_t data_array_temp[100] = {0}; - // uint16_t crc_cal = 0; - // uint32_t read_length = 50; - - // if (fifo_used(&frame_fifo) >= 4 + 4 * data_num) { - // fifo_read_buffer(&frame_fifo, frame_buffer_parse, &read_length, FIFO_READ_AND_CLEAN); - // while (1) { - // if (cnt_ptr < 50) { - // data = frame_buffer_parse[cnt_ptr]; - // cnt_ptr++; - // } - // // printf("char : %0.2X\r\n", data); - - // if ((0 == cnt) && (BY_FRAME_HEAD_1 == data)) { - // frame_parse_busy = 1; // 开始解析 - // cnt = 1; - // data_array_temp[0] = data; - // continue; - // } - - // if ((1 == cnt) && (BY_FRAME_HEAD_2 == data)) { - // cnt = 2; - // data_array_temp[1] = data; - // continue; - // } - - // if ((2 <= cnt) && (cnt < 2 + data_num * sizeof(uint32_t))) { - // data_array_temp[cnt] = data; - // cnt++; - // continue; - // } - - // if (cnt_crc) { - // crc_cal |= ((uint16_t)data << (--cnt_crc * 8)); - // cnt++; - // continue; - // } - - // // printf("GET CRC %0.4X\r\n", crc_cal); - // // printf("CAL CRC %0.4X\r\n", crc16_check((uint8_t *)data_array_temp, 2 + data_num * sizeof(uint32_t))); - - // if (!cnt_crc) { - // if (crc_cal == crc16_check(data_array_temp, 2 + data_num * sizeof(uint32_t))) { - // memcpy(data_array, data_array_temp + 2, data_num * sizeof(uint32_t)); - // fifo_clear(&frame_fifo); // TODO 确认是否有必要清除 - // // lwrb_reset(&lwrb_struct); // 处理完直接清空缓冲区,避免堆积产生处理阻塞 - // memset(data_array_temp, 0, sizeof(data_array_temp)); - // } - - // break; - // } - // } - // } } void by_frame_parse_uart_handle(uint8_t data) { - fifo_write_element(&frame_fifo, data); - // lwrb_write(&lwrb_struct, &data, 1); + // fifo_write_element(&frame_fifo, data); + lwrb_write(&lwrb_ctx, &data, 1); } /** @@ -183,8 +143,4 @@ void by_frame_parse_uart_handle(uint8_t data) */ void by_frame_parse_timer_handle(void) { - static uint8_t time_out = 0; - if (frame_parse_busy) { - time_out--; - } } \ No newline at end of file