湖南东方红建设集团有限公司网站,网站资讯板块的搭建,网页设计与网站建设指标点,seo基础教程文章目录 [toc]cmd-parser库简介cmd-parser库源码获取GW1NSR-4C移植cmd-parser实际测试cmd-parse命令解析器优化 本文是高云FPGA系列教程的第9篇文章。 上一篇文章介绍片上ARM Cortex-M3硬核处理器串口外设的使用#xff0c;演示轮询方式和中断方式接收串口数据#xff0c;并… 文章目录 [toc]cmd-parser库简介cmd-parser库源码获取GW1NSR-4C移植cmd-parser实际测试cmd-parse命令解析器优化 本文是高云FPGA系列教程的第9篇文章。 上一篇文章介绍片上ARM Cortex-M3硬核处理器串口外设的使用演示轮询方式和中断方式接收串口数据并进行回环测试。
本文在上一篇工程的基础上移植cmd-parser串口命令解析器到高云GW1NSR-4C ARM处理器上实现3个命令
led_on点亮LED
led_off熄灭LED
get_sysclk查询处理器频率参考文档Gowin_EMPU(GW1NS-4C)软件编程 参考手册
cmd-parser库简介
cmd-parser是一款非常轻量、高效的命令解析器作者jiejie整个项目只有两个文件cmd.c和cmd.h采用哈希算法进行匹配匹配速度非常快占用资源也很少。
cmd-parser遵循 Apache License v2.0 开源协议。鼓励代码共享和尊重原作者的著作权可以自由的使用、修改源代码也可以将修改后的代码作为开源或闭源软件发布但必须保留原作者版权声明。
开源地址
//Gitee
https://gitee.com/jiejieTop/cmd-parser
//Github
https://github.com/jiejieTop/cmd-parser国内推荐使用Gitee码云平台访问。
cmd-parser库源码获取
访问以上开源地址下载cmd-parse源码或通过如下命令clone到本地
$ git clone https://gitee.com/jiejietop/cmd-parser.git --depth1Cloning into cmd-parser...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 8 (delta 0), reused 8 (delta 0), pack-reused 0
Receiving objects: 100% (8/8), 7.39 KiB | 7.39 MiB/s, done.整个项目非常简单只有两个文件是我们需要的可以参考README文档和示例来帮助我们完成移植。 GW1NSR-4C移植cmd-parser
首先把cmd.c和cmd.h添加到用户目录并在Keil环境添加到工程中。 串口初始化并使能接收中断
void uart0_init(uint32_t BaudRate)
{UART_InitTypeDef UART_InitStruct;NVIC_InitTypeDef InitTypeDef_NVIC;UART_InitStruct.UART_Mode.UARTMode_Tx ENABLE;UART_InitStruct.UART_Mode.UARTMode_Rx ENABLE;UART_InitStruct.UART_Int.UARTInt_Tx DISABLE;UART_InitStruct.UART_Int.UARTInt_Rx ENABLE; //开启接收中断UART_InitStruct.UART_Ovr.UARTOvr_Tx DISABLE;UART_InitStruct.UART_Ovr.UARTOvr_Rx DISABLE;UART_InitStruct.UART_Hstm DISABLE;UART_InitStruct.UART_BaudRate BaudRate;//Baud RateUART_Init(UART0, UART_InitStruct);//Enable UART0 interrupt handlerInitTypeDef_NVIC.NVIC_IRQChannel UART0_IRQn;InitTypeDef_NVIC.NVIC_IRQChannelPreemptionPriority 1;InitTypeDef_NVIC.NVIC_IRQChannelSubPriority 1;InitTypeDef_NVIC.NVIC_IRQChannelCmd ENABLE;NVIC_Init(InitTypeDef_NVIC);
}void UART0_Handler(void)
{char rx 0;if(UART_GetRxIRQStatus(UART0) SET){rx UART_ReceiveChar(UART0);buf[buf_idx] rx;buf_idx;cnt_idle 0;}UART_ClearRxIRQ(UART0);
}定义3个用户命令和对应执行的函数并通过REGISTER_CMD宏完成命令注册。
void led_on(void)
{gpio_write(0xaaaa);
}void led_off(void)
{gpio_write(0);
}void get_sysclk(void)
{printf(SystemCoreClock %d\r\n, SystemCoreClock);printf(APB1 CLK %d\r\n, PCLK1);printf(APB2 CLK %d\r\n, PCLK2);printf(AHB CLK %d\r\n, HCLK);
}REGISTER_CMD(led_on, led_on);
REGISTER_CMD(led_off, led_off);
REGISTER_CMD(get_sysclk, get_sysclk);
主函数中当收到串口命令时进行解析并执行对应的函数
int main(void)
{cmd_init();delay_init();uart0_init(115200); //enable rx interruptprintf(SystemCoreClock %d\r\n, SystemCoreClock);printf(APB1 CLK %d\r\n, PCLK1);printf(APB2 CLK %d\r\n, PCLK2);printf(AHB CLK %d\r\n, HCLK);printf(Hello GW1NSR-4C SoC(ARM Cortex-M3)\r\n);printf(UART0 cmd-parser Example\r\n);while(1){//长时间没有接收到串口数据if(buf_idx ! 0)cnt_idle;else cnt_idle 0;if(cnt_idle 5000) //明显感觉500000{cmd_parsing((char *)buf);//命令解析并执行printf(cmd: %s\r\n, buf);cnt_idle 0;buf_idx 0;memset(buf, 0, sizeof(buf)/sizeof(buf[0]));}}
}实际测试
编译下载运行。发送对应的串口命令可以看到执行了对应的功能。 cmd-parse命令解析器优化
为了满足部分带返回值的函数支持我们对源代码进行一点改动注册的回调函数改为int类型返回值
//typedef void (*cmd_handler)(void);
typedef int (*cmd_handler)(void);//void cmd_parsing(char *str)
int cmd_parsing(char *str)
{cmd_t *index;unsigned int hash _cmd_hash(str);for (index _cmd_begin; index _cmd_end; index _get_next_cmd(index)) {if (hash index-hash) {if (_cmd_match(str, index-cmd) 0) {
// index-handler();return index-handler();break;}}}
}同样对用户函数也进行修改
#include main.huint8_t rx 0;
uint8_t buf[256];
uint16_t buf_idx 0;
uint32_t cnt_idle 0;
uint8_t flag 0;
int ret 0;int led_on(void)
{gpio_write(0xaaaa);return 0;
}int led_off(void)
{gpio_write(0);return 1;
}int get_sysclk(void)
{printf(SystemCoreClock %d\r\n, SystemCoreClock);printf(APB1 CLK %d\r\n, PCLK1);printf(APB2 CLK %d\r\n, PCLK2);printf(AHB CLK %d\r\n, HCLK);return -1;
}REGISTER_CMD(led_on, led_on);
REGISTER_CMD(led_off, led_off);
REGISTER_CMD(get_sysclk, get_sysclk);int main(void)
{cmd_init();delay_init();uart0_init(115200); //enable rx interruptprintf(SystemCoreClock %d\r\n, SystemCoreClock);printf(APB1 CLK %d\r\n, PCLK1);printf(APB2 CLK %d\r\n, PCLK2);printf(AHB CLK %d\r\n, HCLK);printf(Hello GW1NSR-4C SoC(ARM Cortex-M3)\r\n);printf(UART0 RX Interrupt Example\r\n);while(1){//长时间没有接收到串口数据if(buf_idx ! 0)cnt_idle;else cnt_idle 0;if(cnt_idle 5000) //明显感觉500000{ret cmd_parsing((char *)buf);//命令解析并执行printf(cmd: %s, ret %d\r\n, buf, ret);cnt_idle 0;buf_idx 0;memset(buf, 0, sizeof(buf)/sizeof(buf[0]));}}
}测试结果 本文是高云FPGA系列教程的第9篇文章。