rewrite serial/uart code in simulator to support multi-uarts

This commit is contained in:
prife 2013-02-07 23:18:59 +08:00
parent dc089a6444
commit 1c522be515
4 changed files with 87 additions and 80 deletions

View File

@ -62,8 +62,6 @@ _CRTIMP void __cdecl abort(void);
#endif
#endif
#if defined(RT_USING_FINSH)
#include <finsh.h>
void rt_hw_exit(void)
{
rt_kprintf("RT-Thread, bye\n");
@ -81,6 +79,9 @@ void rt_hw_exit(void)
#endif
exit(0);
}
#if defined(RT_USING_FINSH)
#include <finsh.h>
FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_exit, exit, exit rt - thread);
#endif /* RT_USING_FINSH */
@ -97,7 +98,6 @@ void rt_hw_board_init()
//#endif
#if defined(RT_USING_CONSOLE)
rt_hw_serial_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
}

View File

@ -7,20 +7,59 @@
*/
#include <rthw.h>
#include <rtthread.h>
#define _DEBUG_SERIAL 0
#include "serial.h"
#include <stdio.h>
struct rt_device serial_device;
//extern struct serial_int_rx serial_rx;
struct serial_int_rx serial_rx;
#if 0
static FILE *fp = RT_NULL;
#endif
/*@{*/
int seial_save_byte(unsigned char ch, struct serial_device * serial)
{
/* save on rx buffer */
rt_base_t level;
struct rt_device * dev = RT_DEVICE(serial);
/* disable interrupt */
//暂时关闭中断因为要操作uart数据结构
level = rt_hw_interrupt_disable();
/* save character */
serial->serial_rx.rx_buffer[serial->serial_rx.save_index] = ch;
serial->serial_rx.save_index ++;
//下面的代码检查save_index是否已经到到缓冲区尾部如果是则回转到头部称为一个环形缓冲区
if (serial->serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE)
serial->serial_rx.save_index = 0;
//这种情况表示反转后的save_index追上了read_index则增大read_index丢弃一个旧的数据
/* if the next position is read index, discard this 'read char' */
if (serial->serial_rx.save_index == serial->serial_rx.read_index)
{
serial->serial_rx.read_index ++;
if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
serial->serial_rx.read_index = 0;
}
/* enable interrupt */
//uart数据结构已经操作完成重新使能中断
rt_hw_interrupt_enable(level);
/* invoke callback */
if (dev->rx_indicate != RT_NULL)
{
rt_size_t rx_length;
/* get rx length */
rx_length = serial->serial_rx.read_index > serial->serial_rx.save_index ?
SERIAL_RX_BUFFER_SIZE - serial->serial_rx.read_index + serial->serial_rx.save_index :
serial->serial_rx.save_index - serial->serial_rx.read_index;
dev->rx_indicate(dev, rx_length);
}
return 0;
}
/* RT-Thread Device Interface */
/**
@ -28,14 +67,15 @@ static FILE *fp = RT_NULL;
*/
static rt_err_t rt_serial_init(rt_device_t dev)
{
struct serial_device * serial = SERIAL_DEVICE(dev);
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
rt_memset(serial_rx.rx_buffer, 0,
sizeof(serial_rx.rx_buffer));
serial_rx.read_index = 0;
serial_rx.save_index = 0;
rt_memset(serial->serial_rx.rx_buffer, 0,
sizeof(serial->serial_rx.rx_buffer));
serial->serial_rx.read_index = 0;
serial->serial_rx.save_index = 0;
}
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
@ -62,6 +102,7 @@ static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_
{
rt_uint8_t *ptr;
rt_err_t err_code;
struct serial_device * serial = SERIAL_DEVICE(dev);
ptr = buffer;
err_code = RT_EOK;
@ -76,16 +117,16 @@ static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial_rx.read_index != serial_rx.save_index)
if (serial->serial_rx.read_index != serial->serial_rx.save_index)
{
/* read a character */
*ptr++ = serial_rx.rx_buffer[serial_rx.read_index];
*ptr++ = serial->serial_rx.rx_buffer[serial->serial_rx.read_index];
size--;
/* move to next position */
serial_rx.read_index ++;
if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
serial_rx.read_index = 0;
serial->serial_rx.read_index ++;
if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
serial->serial_rx.read_index = 0;
}
else
{
@ -149,7 +190,7 @@ static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
/*
* serial register
*/
static rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag)
rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag)
{
RT_ASSERT(device != RT_NULL);
#if _DEBUG_SERIAL==1
@ -170,8 +211,8 @@ static rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_u
return rt_device_register(device, name, (rt_uint16_t)(RT_DEVICE_FLAG_RDWR | flag));
}
rt_err_t rt_hw_serial_init(void)
rt_err_t rt_hw_serial_init(struct serial_device * serial, char * name)
{
return rt_hw_serial_register(&serial_device, RT_CONSOLE_DEVICE_NAME,
return rt_hw_serial_register(RT_DEVICE(serial), name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
}

View File

@ -11,6 +11,7 @@
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rtdevice.h>
#define SERIAL_RX_BUFFER_SIZE 80
struct serial_int_rx
{
@ -18,5 +19,14 @@ struct serial_int_rx
rt_uint32_t read_index, save_index;
};
rt_err_t rt_hw_serial_init(void);
struct serial_device
{
struct rt_device dev;
struct serial_int_rx serial_rx;
};
#define SERIAL_DEVICE(dev) ((struct serial_device *)(dev))
int seial_save_byte(unsigned char ch, struct serial_device * serial);
rt_err_t rt_hw_serial_init(struct serial_device * serial, char * name);
#endif

View File

@ -10,9 +10,9 @@
#include <stdio.h>
#include "serial.h"
struct serial_int_rx serial_rx;
extern struct rt_device serial_device;
struct serial_device serial1;
#define SAVEKEY(key) seial_save_byte(key, &serial1)
#ifdef _WIN32
/*
* Handler for OSKey Thread
@ -23,6 +23,7 @@ static DWORD OSKey_ThreadID;
static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam);
void rt_hw_usart_init(void)
{
rt_hw_serial_init(&serial1, RT_CONSOLE_DEVICE_NAME);
/*
* create serial thread that receive key input from keyboard
*/
@ -60,7 +61,6 @@ void rt_hw_usart_init(void)
#include <termios.h> /* for tcxxxattr, ECHO, etc */
#include <unistd.h> /* for STDIN_FILENO */
static void * ThreadforKeyGet(void * lpParam);
static pthread_t OSKey_Thread;
void rt_hw_usart_init(void)
@ -74,57 +74,7 @@ void rt_hw_usart_init(void)
}
}
#endif
/*
* () 0xe04b
* () 0xe048
* () 0xe04d
* () 0xe050
*/
static int savekey(unsigned char key)
{
/* save on rx buffer */
{
rt_base_t level;
/* disable interrupt */
//暂时关闭中断因为要操作uart数据结构
level = rt_hw_interrupt_disable();
/* save character */
serial_rx.rx_buffer[serial_rx.save_index] = key;
serial_rx.save_index ++;
//下面的代码检查save_index是否已经到到缓冲区尾部如果是则回转到头部称为一个环形缓冲区
if (serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE)
serial_rx.save_index = 0;
//这种情况表示反转后的save_index追上了read_index则增大read_index丢弃一个旧的数据
/* if the next position is read index, discard this 'read char' */
if (serial_rx.save_index == serial_rx.read_index)
{
serial_rx.read_index ++;
if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
serial_rx.read_index = 0;
}
/* enable interrupt */
//uart数据结构已经操作完成重新使能中断
rt_hw_interrupt_enable(level);
}
/* invoke callback */
if (serial_device.rx_indicate != RT_NULL)
{
rt_size_t rx_length;
/* get rx length */
rx_length = serial_rx.read_index > serial_rx.save_index ?
SERIAL_RX_BUFFER_SIZE - serial_rx.read_index + serial_rx.save_index :
serial_rx.save_index - serial_rx.read_index;
serial_device.rx_indicate(&serial_device, rx_length);
}
return 0;
}
#ifdef _WIN32
static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam)
#else
@ -153,6 +103,12 @@ void restore_stty(void)
static void * ThreadforKeyGet(void * lpParam)
#endif /* not _WIN32*/
{
/*
* () 0xe04b
* () 0xe048
* () 0xe04d
* () 0xe050
*/
unsigned char key;
#ifndef _WIN32
@ -173,20 +129,20 @@ static void * ThreadforKeyGet(void * lpParam)
if (key == 0x48) //up key , 0x1b 0x5b 0x41
{
savekey(0x1b);
savekey(0x5b);
savekey(0x41);
SAVEKEY(0x1b);
SAVEKEY(0x5b);
SAVEKEY(0x41);
}
else if (key == 0x50)//0x1b 0x5b 0x42
{
savekey(0x1b);
savekey(0x5b);
savekey(0x42);
SAVEKEY(0x1b);
SAVEKEY(0x5b);
SAVEKEY(0x42);
}
continue;
}
#endif
savekey(key);
SAVEKEY(key);
}
} /*** ThreadforKeyGet ***/