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

View File

@ -7,20 +7,59 @@
*/ */
#include <rthw.h> #include <rthw.h>
#include <rtthread.h>
#define _DEBUG_SERIAL 0 #define _DEBUG_SERIAL 0
#include "serial.h" #include "serial.h"
#include <stdio.h> #include <stdio.h>
struct rt_device serial_device;
//extern struct serial_int_rx serial_rx;
struct serial_int_rx serial_rx;
#if 0 #if 0
static FILE *fp = RT_NULL; static FILE *fp = RT_NULL;
#endif #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 */ /* RT-Thread Device Interface */
/** /**
@ -28,14 +67,15 @@ static FILE *fp = RT_NULL;
*/ */
static rt_err_t rt_serial_init(rt_device_t dev) 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_ACTIVATED))
{ {
if (dev->flag & RT_DEVICE_FLAG_INT_RX) if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{ {
rt_memset(serial_rx.rx_buffer, 0, rt_memset(serial->serial_rx.rx_buffer, 0,
sizeof(serial_rx.rx_buffer)); sizeof(serial->serial_rx.rx_buffer));
serial_rx.read_index = 0; serial->serial_rx.read_index = 0;
serial_rx.save_index = 0; serial->serial_rx.save_index = 0;
} }
dev->flag |= RT_DEVICE_FLAG_ACTIVATED; 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_uint8_t *ptr;
rt_err_t err_code; rt_err_t err_code;
struct serial_device * serial = SERIAL_DEVICE(dev);
ptr = buffer; ptr = buffer;
err_code = RT_EOK; 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 */ /* disable interrupt */
level = rt_hw_interrupt_disable(); 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 */ /* read a character */
*ptr++ = serial_rx.rx_buffer[serial_rx.read_index]; *ptr++ = serial->serial_rx.rx_buffer[serial->serial_rx.read_index];
size--; size--;
/* move to next position */ /* move to next position */
serial_rx.read_index ++; serial->serial_rx.read_index ++;
if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE) if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
serial_rx.read_index = 0; serial->serial_rx.read_index = 0;
} }
else else
{ {
@ -149,7 +190,7 @@ static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
/* /*
* serial register * 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); RT_ASSERT(device != RT_NULL);
#if _DEBUG_SERIAL==1 #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)); 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); RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
} }

View File

@ -11,6 +11,7 @@
#ifndef __RT_HW_SERIAL_H__ #ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__ #define __RT_HW_SERIAL_H__
#include <rtdevice.h>
#define SERIAL_RX_BUFFER_SIZE 80 #define SERIAL_RX_BUFFER_SIZE 80
struct serial_int_rx struct serial_int_rx
{ {
@ -18,5 +19,14 @@ struct serial_int_rx
rt_uint32_t read_index, save_index; 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 #endif

View File

@ -10,9 +10,9 @@
#include <stdio.h> #include <stdio.h>
#include "serial.h" #include "serial.h"
struct serial_int_rx serial_rx; struct serial_device serial1;
extern struct rt_device serial_device;
#define SAVEKEY(key) seial_save_byte(key, &serial1)
#ifdef _WIN32 #ifdef _WIN32
/* /*
* Handler for OSKey Thread * Handler for OSKey Thread
@ -23,6 +23,7 @@ static DWORD OSKey_ThreadID;
static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam); static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam);
void rt_hw_usart_init(void) void rt_hw_usart_init(void)
{ {
rt_hw_serial_init(&serial1, RT_CONSOLE_DEVICE_NAME);
/* /*
* create serial thread that receive key input from keyboard * 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 <termios.h> /* for tcxxxattr, ECHO, etc */
#include <unistd.h> /* for STDIN_FILENO */ #include <unistd.h> /* for STDIN_FILENO */
static void * ThreadforKeyGet(void * lpParam); static void * ThreadforKeyGet(void * lpParam);
static pthread_t OSKey_Thread; static pthread_t OSKey_Thread;
void rt_hw_usart_init(void) void rt_hw_usart_init(void)
@ -74,57 +74,7 @@ void rt_hw_usart_init(void)
} }
} }
#endif #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 #ifdef _WIN32
static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam) static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam)
#else #else
@ -153,6 +103,12 @@ void restore_stty(void)
static void * ThreadforKeyGet(void * lpParam) static void * ThreadforKeyGet(void * lpParam)
#endif /* not _WIN32*/ #endif /* not _WIN32*/
{ {
/*
* () 0xe04b
* () 0xe048
* () 0xe04d
* () 0xe050
*/
unsigned char key; unsigned char key;
#ifndef _WIN32 #ifndef _WIN32
@ -173,20 +129,20 @@ static void * ThreadforKeyGet(void * lpParam)
if (key == 0x48) //up key , 0x1b 0x5b 0x41 if (key == 0x48) //up key , 0x1b 0x5b 0x41
{ {
savekey(0x1b); SAVEKEY(0x1b);
savekey(0x5b); SAVEKEY(0x5b);
savekey(0x41); SAVEKEY(0x41);
} }
else if (key == 0x50)//0x1b 0x5b 0x42 else if (key == 0x50)//0x1b 0x5b 0x42
{ {
savekey(0x1b); SAVEKEY(0x1b);
savekey(0x5b); SAVEKEY(0x5b);
savekey(0x42); SAVEKEY(0x42);
} }
continue; continue;
} }
#endif #endif
savekey(key); SAVEKEY(key);
} }
} /*** ThreadforKeyGet ***/ } /*** ThreadforKeyGet ***/