完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在 serial.c 的 rt_serial_write 中
/* DMA mode Tx */ /* allocate a data node */ struct STM32_serial_data_node* data_node = (struct stm32_serial_data_node*) rt_malloc (sizeof(struct stm32_serial_data_node)); if (data_node == RT_NULL) { /* set error code */ err_code = -RT_ENOMEM; } 只看到rt_malloc 申请内存块,没有看到释放内存块,时间长了就申请不到内存了。好象以前看到过这个问题,应该被修正了,但今天重新check out代码,还是这样的,不知道何故。 另外,建议将串口封装得更加方便些,可不可以这样做: #ifdef RT_USING_UART1 #if (UART1_RX_MODE == INT) struct stm32_serial_int_rx uart1_int_rx; #endif #if (UART1_RX_MODE == DMA) struct stm32_serial_dma_rx uart1_dma_rx; #endif #if (UART1_TX_MODE == INT) struct stm32_serial_int_tx uart1_int_tx; #endif #if (UART1_TX_MODE == DMA) struct stm32_serial_dma_tx uart1_dma_tx; #endif struct stm32_serial_device uart1 = { USART1, #if (UART1_RX_MODE==INT) &uart1_int_rx, #else RT_NULL, #endif #if (UART1_RX_MODE==DMA) &uart1_dma_rx, #else RT_NULL, #endif #if (UART1_TX_INT==INT) &uart1_int_tx, #else RT_NULL, #endif #if (UART1_TX_DMA==DMA) &uart1_dma_tx #else RT_NULL #endif }; struct rt_device uart1_device; #endif 可以将所有串口的参数定义一个二维数组,初始化采用条件编译,不会增加空间,用户也可以不用管细节,直接定义一下,就能初始化。 当然工作量有些大,毕竟uart.c uart.h serial.c serial.h stm32f10x_it.c这些都需要改动。 但我想单片机用得最多的外设还是串口,这样能减少系统出错的可能性,用户方便,才是好推广的条件之一。 |
|
相关推荐
4个回答
|
|
抽空把serial device改了一下,将中断发送、接收缓冲改为动态申请,缓冲大小在rtconfig.h中定义
同时将接收、发送模式定义也放到rtconfig.h中,采用条件编译。 例如在rtconfig.h中 #define RT_USING_UART1 #define UART1_BAUDRATE 115200 #define UART1_TX_MODE INT #define UART1_RX_MODE POLL #define UART1_RX_BUF_SIZE 512 #define UART1_TX_BUF_SIZE 128 #define RT_USING_UART2 #define UART2_BAUDRATE 9600 #define UART2_TX_MODE INT #define UART2_RX_MODE POLL #define UART2_RX_BUF_SIZE 256 #define UART2_TX_BUF_SIZE 128 #define RT_USING_UART3 #define UART3_BAUDRATE 115200 #define UART3_TX_MODE INT #define UART3_RX_MODE POLL #define UART3_RX_BUF_SIZE 512 #define UART3_TX_BUF_SIZE 128 在serial.c中设备初始化修改为 rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct stm32_serial_device *serial,rt_uint16_t rx_bufsize,rt_uint16_t tx_bufsize) { RT_ASSERT(device != RT_NULL); rt_uint8_t* uart1_rx_buf = rt_malloc (rx_bufsize);//仅为测试,未用内存申请检查 rt_uint8_t* uart1_tx_buf = rt_malloc (tx_bufsize); serial->int_rx->rx_buffer=uart1_rx_buf; serial->int_rx->rx_buffer_size=rx_bufsize; serial->int_tx->tx_buffer=uart1_tx_buf; serial->int_tx->tx_buffer_size=tx_bufsize; device->type = RT_Device_Class_Char; device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; device->init = rt_serial_init; device->open = rt_serial_open; device->close = rt_serial_close; device->read = rt_serial_read; device->write = rt_serial_write; device->control = rt_serial_control; device->private = serial; /* register a character device */ return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); } 在stm32f10x_it.c中对中断也进行了条件编译 例如: void USART2_IRQHandler(void) { #ifdef RT_USING_UART2 extern struct rt_device uart2_device; extern void rt_hw_serial_isr(struct rt_device *device); /* enter interrupt */ rt_interrupt_enter(); rt_hw_serial_isr(&uart2_device); /* leave interrupt */ rt_interrupt_leave(); #endif } 现在DMA还没考虑好,因为一个DMA通道有几个设备共用,需要好好规划一下,看用什么方式比较好。 请bernard 提些意见和建议 |
|
|
|
可能在设备打开时进行缓冲区检查,没有申请就申请,
在设备关闭时释放内存,这样比较好 对了,关于串口设备的int_rx,int_tx也重新定义了 struct stm32_serial_int_rx { rt_uint8_t *rx_buffer; rt_uint16_t rx_buffer_size; rt_uint32_t read_index, save_index; }; struct stm32_serial_int_tx { rt_uint8_t *tx_buffer; rt_uint16_t tx_buffer_size; rt_uint32_t write_index, save_index; }; |
|
|
|
很奇怪,在编译中选择优化为低,长时间后会死,而且不出现RTT的错误信息(没有SP什么的寄存器值打印出来),中断后能继续执行,但单步不知道会走到什么地方,经常执行到USART_GetITStatus里面。是不是系统负荷太重?
在编译优化选择为最高时,好象正常(已经测试了2个小时) 测试程序是创建两个线程,一个为GPS,一个为GSM,分别从usart1和usart2读数据,然后通过usart3(rt_kpringf())输出,对于usart3用了信号量进行访问互诉。 在NVIC中现在设置为: static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); #ifdef RT_USING_UART1 /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart1_conf.INT_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #ifdef RT_USING_UART2 /* Enable the USART2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart2_conf.INT_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #ifdef RT_USING_UART3 /* Enable the USART3 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart3_conf.INT_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif } 自己想不明白,请版主指点 gsm.c为: #include "wchar.h" #include "gsm.h" struct rt_thread gsm_thread; static char gsm_thread_stack[1024]; rt_device_t gsm_device; extern struct rt_semaphore uart3_sem; struct rt_semaphore gsm_sem; static rt_err_t gsm_rx_ind(rt_device_t dev, rt_size_t size) { /* release semaphore to let gps thread rx data */ rt_sem_release(&gsm_sem); return RT_EOK; } void gsm_set_device(char* device_name) { rt_device_t dev = RT_NULL; dev = rt_device_find(device_name); if (dev != RT_NULL && rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) == RT_EOK) { if (gsm_device != RT_NULL) { /* close old finsh device */ rt_device_close(gsm_device); } rt_device_set_rx_indicate(dev, gsm_rx_ind); gsm_device = dev; } else { rt_kprintf("Can not find GSM device:%s ", device_name); } } void gsm_buf_clear(void) { char ch; while(rt_sem_take(&gsm_sem,0)==RT_EOK){}; while(1==rt_device_read(gsm_device,0,&ch,1)){}; } rt_err_t at_cmd(char * cmd,char * resultchar,int size,int waittime) { unsigned char len; char *ptr; char ch; ptr=resultchar; rt_memset(resultchar,0,size); len=rt_strlen(cmd); gsm_buf_clear(); rt_device_write(gsm_device,0,cmd,len); rt_thread_delay(waittime); while(rt_sem_take(&gsm_sem, waittime) == RT_EOK) { if(1==rt_device_read(gsm_device, 0, &ch,1)) *ptr++=ch; } return (ptr-resultchar); } rt_bool_t at_test(void) { rt_err_t len; char buf[16]; rt_device_write(gsm_device,0,"AT ",3); rt_thread_delay(20); rt_memset(buf,0,16); len=rt_device_read(gsm_device, 0, &buf[0],16); if ((len>5)&&(rt_strstr(buf,"OK "))) return RT_TRUE; else return RT_FALSE; } void gsm_thread_entry(void* parameter) { // int pos ; static rt_uint16_t cont=0; static char buf[512]; // rt_thread_delay(1500); gsm_set_device("gsm"); // while (RT_TRUE!=at_test()); while (1) { at_cmd("AT+CMGF=0 ",buf,sizeof(buf),20); if (rt_sem_take(&uart3_sem, -1) == RT_EOK) { rt_kprintf("%s ",&buf[0]); rt_sem_release(&uart3_sem); } at_cmd("AT+CMGR=8 ",buf,sizeof(buf),20); if (rt_sem_take(&uart3_sem, -1) == RT_EOK) { rt_kprintf("%s ",&buf[0]); rt_kprintf("COUNTER=>> %d ",cont++); rt_sem_release(&uart3_sem); } // rt_thread_delay(100); } } void rt_gsm_thread_init(void) { rt_sem_init(&gsm_sem, "gsm_sem", 0, 0); rt_thread_init(&gsm_thread, "gsm", gsm_thread_entry, RT_NULL, &gsm_thread_stack[0], sizeof(gsm_thread_stack), 21, 100); rt_thread_startup(&gsm_thread); } gps.c为: #include #include #include "gps.h" |
|
|
|
我现在的想法是将串口的一些基本操作在usart中实现,比如将rt_hw_usart_init()改为初始化一个串口硬件,包括管脚定义,发送/接收模式,发送/接收缓冲区大小等。重新定义一个rt_hw_usart_init_all()用来初始化所用串口。
现在的结构和你原先的有些不一样。每个串口可以定义不同的接收/送发缓冲区大小,在设备注册时指定大小,设备打开时申请缓冲区、打开中断,设备关闭时释放缓冲区、关闭中断。这样灵活些,因为实际使用时,可能有的串口只是小量数据,而有的串口需要大量的数据,将缓冲区定义成一样大,有些浪费(单片机RAM是最珍贵资源)。 关于DMA传输,现在还没有想好,打算也用动态申请的办法。 关于NVIC优先级分组的问题,是刚开始时老是跑跑就死,所以调整一下优先级试试的,后来还是改了编译优化级别才正常的。回头再改回原来的测试下(顺便问一下,现有的系统调度支持抢占优先级吗)。 其他的芯片不太了解,版主认为将usart.c和serial.c分开来,这个serial.c的重用性如何?如果不是很高的话,就没有多大必要了,就针对不同的平台采用不同的serial好了。 看了一下,版主的rt_hw_serial_isr()好象不可重入吧,请明确一下 因为如果3个串口同时有大量的数据的话,可重入的话就不怕了。我猜测我上面碰到的问题可能是数据量太大了 (usart1,115200;usart2,9600;usart3,115200),而且三个口一直处于收发状态,可能串口这方面的负荷太重了。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
694 浏览 0 评论
3104 浏览 0 评论
如何使用python调起UDE STK5.2进行下载自动化下载呢?
2368 浏览 0 评论
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
2833 浏览 0 评论
获奖公布!2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
30548 浏览 11 评论
72589 浏览 21 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-16 07:25 , Processed in 0.667922 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号