2440平台处理串口接收数据采用信号量方式会当机
2440硬件平台,采用0.4.0beta版本,串口中断接收数据,完成后调用rt_sem_release通知任务处理,处理任务调用rt_sem_take等到信号量后开始处理数据,测试运行,不稳定,有时几分钟,有时半个钟,ARM就出现undefined异常,R14(LR)0x300003b4,看编译后的map文件,rt_hw_context_switch_to 0x300003ac ARM Code 24context_rvds.o(.text),说明此时代码运行在这个函数里面出现了异常,再做一实验:不采用信号量方式通知处理任务,而是处理任务直接延时tick,然后读接收buffer里面的数据做处理,测试运行了1个晚上都没有发现上面这种异常现象,
分析:串口使用信号量的手法和finsh写的手法一摸一样,于是猜想可能finsh那边也会出同样问题,再做一次验证:采用串口调试助手:200ms时间间隔自动发送list_mem()命令,测试发现15分钟左右就出现了上面这种内核切换线程异常
哪位有2440的硬件平台,帮忙测试看看,看是否有这样的现象? 请给个串口接收代码吧 初始化中:
{
//创建接收数据的信号量
modem.rxdsem = rt_sem_create("modem_sem", 0, RT_IPC_FLAG_FIFO);
rt_device_set_rx_indicate(modem.device, _modem_rxind);
}
rt_err_t _modem_rxind(rt_device_t dev, rt_size_t size)
{
rt_sem_release(modem.rxdsem);
return RT_EOK;
}
//处理线程
static void _modem_rxd_thread_entry(void* parameter)
{
rt_device_open(modem.device, RT_DEVICE_OFLAG_RDWR);
while (1)
{
if (rt_sem_take(modem.rxdsem, RT_WAITING_FOREVER) != RT_EOK) continue;
/*read rx ind data*/
readcnt = rt_device_read(modem.device, 0, &buff, rxbuff_maxsize - okindex);
okindex += readcnt;
//下面是处理数据过程。。。。
okindex = 0;
}
}
读串口buffer里面的数据
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct serial_device* serial = (struct serial_device*)dev;
RT_ASSERT(dev != RT_NULL);
ptr = (rt_uint8_t*)buffer + pos;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* interrupt mode Rx */
while (size)
{
/* interrupt receive */
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial->rxd.read_index != serial->rxd.save_index)
{
*ptr = serial->rxd.rx_buffer;
serial->rxd.read_index++;
if (serial->rxd.read_index == RT_UART_BUFFER_SIZE)
serial->rxd.read_index = 0;
}
else
{
/* no data in rx buffer */
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
ptr ++; size --;
}
}
else
{
/* polling mode */
/* not support right now */
RT_ASSERT(0);
}
return (rt_uint32_t)ptr - ((rt_uint32_t)buffer + pos);
}
串口中断调用的函数
static void _rt_serial_handle_rxd(struct serial_device* serial)
{
rt_uint8_t Buffer;
rt_uint8_t BufferCount;
rt_uint8_t* pBuf;
rt_uint8_t freebuffer;
rt_uint8_t receive_size;
if (serial == RT_NULL)
return;
pBuf = Buffer;
receive_size = 0;
BufferCount = Uart_ReadBytesfromFIFO(serial->uart.Port, Buffer);
if (serial->rxd.read_index <= serial->rxd.save_index)
{freebuffer = RT_UART_BUFFER_SIZE - (serial->rxd.save_index - serial->rxd.read_index) - 1;}
else
{freebuffer = serial->rxd.read_index - serial->rxd.save_index - 1;}
if (freebuffer == 0)
receive_size = RT_UART_BUFFER_SIZE - 1;
while (freebuffer && BufferCount)
{
serial->rxd.rx_buffer = *pBuf++;
if (serial->rxd.save_index == RT_UART_BUFFER_SIZE)
serial->rxd.save_index = 0;
receive_size++;
freebuffer--;
BufferCount--;
}
/* invoke callback */
if (serial->parent.rx_indicate != RT_NULL)
{
serial->parent.rx_indicate(&serial->parent, receive_size);
}
}
还请帮忙验证一下,看问题出在哪里 学习了!!
页:
[1]