freeRTOS操作系统机器人实现
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
7.0 KiB

3 days ago
#include "bsp_config.h"
#ifdef USE_PRINT
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "main.h"
#include "bsp_uart.h"
#include "rd_time.h"
#include "bsp_config.h"
#ifdef USE_FREERTOS
#include "cmsis_os.h"
#endif
#ifndef PRINT_ID
#include "bsp_usb.h"
#endif
#ifdef USE_LUA_ST
extern volatile uint8_t g_lua_stop_request;
#endif
// 定义流控字符
#define CHAR_XOFF 0x13
#define CHAR_XON 0x11
#define RINGBUF_LOW_WATER_MARK 64
// 全局标志:是否已经发送了 XOFF
volatile uint8_t g_flow_control_paused = 0;
TComCtrl *g_ptUartCtrl;
int USART_Send(char *_pBuffer, uint32_t _iSize)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10,GPIO_PIN_SET);
TUartUserData *ptUartUserData = (TUartUserData *)g_ptUartCtrl->m_pUserData;
int iRet = HAL_UART_Transmit(ptUartUserData->m_uart, (uint8_t *)_pBuffer, _iSize, 100);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10,GPIO_PIN_RESET);
return iRet;
}
/*int Dev01check(char *_pBuffer, uint32_t _iSize)
{
static int iStat = 0;
for (int i = 0; i < _iSize; i++)
{
switch (iStat)
{
case 0:
if (_pBuffer[i] == 0x10)
{
iStat = 1;
continue;
}
return -1;
case 1:
if (_pBuffer[i] == 0x11)
{
iStat = 2;
continue;
}
else
{
iStat = 0;
return 0;
}
case 2:
if (_pBuffer[i] == 0x12)
{
iStat = 0;
return 3;
}
else
{
iStat = 0;
return 0;
}
break;
default:
break;
}
}
return -1;
}
void Dev01decode(const char *_pBuffer, uint32_t _iSize)
{
printf("This is dev 01 \r\n");
}
int Dev02check(char *_pBuffer, uint32_t _iSize)
{
if (_iSize < 3) return 0;
if (_pBuffer[0] != 0x20)
{
return -1;
}
if (_pBuffer[1] != 0x21)
{
return -1;
}
if (_pBuffer[2] == 0x22)
{
return 3;
}
else
{
return -1;
}
}
void Dev02decode(const char *_pBuffer, uint32_t _iSize)
{
printf("This is dev 02 \r\n");
}
int Dev03check(char *_pBuffer, uint32_t _iSize)
{
if (_iSize < 2) return 0; // 至少要有头和长度域
// 1. 找头
if (_pBuffer[0] != 0xAA) return -1;
// 2. 读长度 (假设第2个字节是长度)
uint8_t len = _pBuffer[1];
uint32_t total_len = 2 + len + 1; // 头+长度域+数据+尾
// 3. 检查数据够不够
if (_iSize < total_len) return 0; // 数据没到齐,继续等
// 4. 验尾
if (_pBuffer[total_len - 1] == 0x55) // 检查最后一个字节
{
return total_len; // 成功
}
else
{
return -1; // 尾不对,丢弃头,重新找
}
}
void Dev03decode(const char *_pBuffer, uint32_t _iSize)
{
printf("This is dev 03 \r\n");
}*/
WEAK void Myprint_Init(void)
{
#ifdef PRINT_ID
TUartUserData *ptUartUserData = UART_userdata_init(PRINT_ID, 115200, 4096);
g_ptUartCtrl = rd_ComCreate(NULL, NULL, USART_Send, ptUartUserData->m_buf_size, ptUartUserData);
UART_IT_init(g_ptUartCtrl);
#else
g_ptUartCtrl = bsp_usb_init();
#endif
// g_ptUartCtrl = rd_ComCreate(Dev01check, Dev01decode, USART_Send, ptUartUserData->m_buf_size, ptUartUserData);
// rd_ComAddDev(g_ptUartCtrl, Dev02check, Dev02decode);
// rd_ComAddDev(g_ptUartCtrl, Dev03check, Dev03decode);
}
WEAK void Myprint_timer(void)
{
//rd_ComSendProc(g_ptUartCtrl);
}
WEAK void Myprint_IRQHandler(void)
{
#ifdef PRINT_ID
UART_DMA_RX_IRQHandler(g_ptUartCtrl);
#endif
}
/**
* @brief ( \n -> \r\n )
*
*/
WEAK int Myprint_putchar(uint8_t ch)
{
char tx_buf[2];
if (ch == '\n')
{
// 遇到换行,发送 \r\n
tx_buf[0] = '\r';
tx_buf[1] = '\n';
if (rd_ComSend(g_ptUartCtrl, tx_buf, 2) < 0) return EOF;
return 2;
}
else
{
// 普通字符
tx_buf[0] = ch;
if (rd_ComSend(g_ptUartCtrl, tx_buf, 1) < 0) return EOF;
return 1;
}
}
/**
* @brief fputc ()
* printf, putchar
*/
int fputc(int ch, FILE *f)
{
if (Myprint_putchar((uint8_t)ch) == EOF)
{
return EOF;
}
return ch;
}
/**
* @brief _write ()
* fwrite, printf
* fputc
*/
ssize_t _write(int file, char *ptr, ssize_t len)
{
if (file == STDOUT_FILENO || file == STDERR_FILENO || file == STDIN_FILENO)
{
ssize_t i;
for (i = 0; i < len; i++)
{
if (fputc(ptr[i], stdout) == EOF)
{
break;
}
}
return i;
}
errno = EBADF;
return -1;
}
/**
* @brief ( RingBuffer)
* 0x04 EOF
*/
WEAK void Myprint_getchar(char *ch)
{
while (1)
{
int ret;
__disable_irq();
ret = rd_ComRead(g_ptUartCtrl, ch, 1);
__enable_irq();
if (ret == 1)
{
return;
}
#ifdef USE_FREERTOS
osDelay(1);
#endif
#ifdef USE_TIMER
// 轮询发送
void tim_main_loop(void);
tim_main_loop();
#endif
// 无数据,低功耗等待 (确保 SysTick 或其他中断能唤醒)
//__WFI();
}
}
/**
* @brief fgetc ()
* getchar, fgetc
*/
int fgetc(FILE *f)
{
char ch;
Myprint_getchar(&ch);
if ((uint8_t)ch == 0x04)
{
#ifdef USE_LUA_ST
g_lua_stop_request = 1;
#endif
return EOF;
}
return (int)(unsigned char)ch;
}
/**
* @brief _read ()
* fread, scanf, read
* fgetc
*/
ssize_t _read(int file, char *ptr, ssize_t len)
{
if (file == STDIN_FILENO)
{
int i = 0;
while (i < len)
{
char ch;
Myprint_getchar(&ch);
ptr[i++] = ch;
// 遇到换行符,通常认为一行结束 (配合 scanf)
// 注意:这里不自动丢弃 \r 后的 \n,由上层应用决定
if (ch == '\r' || ch == '\n')
{
break;
}
}
return i;
}
errno = EBADF;
return -1;
}
void Flow_control_before(void)
{
TUartUserData *ptUartUserData = (TUartUserData *)g_ptUartCtrl->m_pUserData;
int space_left = ptUartUserData->m_buf_size - rd_RingbufferDataLen(g_ptUartCtrl->m_stComBuf.m_ptRecv);
if (space_left < RINGBUF_LOW_WATER_MARK && !g_flow_control_paused)
{
fputc(CHAR_XOFF, stdout);
g_flow_control_paused = 1;
Rd_Delay(1);
}
}
void Flow_control_after(void)
{
if (g_flow_control_paused)
{
fputc(CHAR_XON, stdout);
g_flow_control_paused = 0;
Rd_Delay(1);
}
}
#endif