linux串口终端驱动——s3c6410平台(三)

发布者:心境恬淡最新更新时间:2022-06-15 来源: eefocus关键字:linux 手机看文章 扫描二维码
随时随地手机看文章

上一篇关注的是tty上层字符层面的操作和注册,这一篇主要关注线程的注册,如何与上层建筑联系起来。


一、 tty_ldisc.c提供了tty_register_ldisc()接口用于注册线路规程,例如/driver/char/n_tty.c文件则针对N_TTY线路规程实现了具体的tty_disc结构体中的成员。


tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY)


其中有


#define N_TTY 0


struct tty_ldisc_ops tty_ldisc_N_TTY = {

.magic           = TTY_LDISC_MAGIC,

.name            = "n_tty",

.open            = n_tty_open,

.close           = n_tty_close,

.flush_buffer    = n_tty_flush_buffer,

.chars_in_buffer = n_tty_chars_in_buffer,

.read            = n_tty_read,

.write           = n_tty_write,

.ioctl           = n_tty_ioctl,

.set_termios     = n_tty_set_termios,

.poll            = n_tty_poll,

.receive_buf     = n_tty_receive_buf,

.write_wakeup    = n_tty_write_wakeup

};


对应的原型为


struct tty_ldisc_ops {

int magic;

char *name;

int num;

int flags;


/*

* The following routines are called from above.

*/

int (*open)(struct tty_struct *);

void (*close)(struct tty_struct *);

void (*flush_buffer)(struct tty_struct *tty);

ssize_t  (*chars_in_buffer)(struct tty_struct *tty);

ssize_t  (*read)(struct tty_struct * tty, struct file * file,

unsigned char __user * buf, size_t nr);

ssize_t  (*write)(struct tty_struct * tty, struct file * file,

const unsigned char * buf, size_t nr);

int (*ioctl)(struct tty_struct * tty, struct file * file,

unsigned int cmd, unsigned long arg);

long (*compat_ioctl)(struct tty_struct * tty, struct file * file,

unsigned int cmd, unsigned long arg);

void (*set_termios)(struct tty_struct *tty, struct ktermios * old);

unsigned int (*poll)(struct tty_struct *, struct file *,

    struct poll_table_struct *);

int (*hangup)(struct tty_struct *tty);

/*

* The following routines are called from below.

*/

void (*receive_buf)(struct tty_struct *, const unsigned char *cp,

      char *fp, int count);


void(*write_wakeup)(struct tty_struct *);

struct  module *owner;

int refcount;

};



struct tty_ldisc {

struct tty_ldisc_ops *ops;

int refcount;

};


二、而tty_register_ldisc函数则把具体的struct tty_disc添加到线程安装表中的对应编号处,本例为0出,因为N_TTY为0。注:这里还没有和tty上层连接起来,只是添加到了线程规划表中。


源码如下:


/* Line disc dispatch table */

static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];


所有安装线程表


/**

 *tty_register_ldisc-install a line discipline安装一个线程规划

 *@disc: ldisc number ldisc的编号

 *@new_ldisc: pointer to the ldisc object指向新安装的ldsic的操作函数

 *

 *Installs a new line discipline into the kernel. The discipline

 *is set up as unreferenced and then made available to the kernel

 *from this point onwards.

 *

 *Locking:加锁保护

 *takes tty_ldisc_lock to guard against ldisc races

 */

int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)


对照tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY)和


static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]即可看明

{

unsigned long flags;

int ret = 0;


if (disc < N_TTY || disc >= NR_LDISCS)判断编号是否符合

return -EINVAL;

spin_lock_irqsave(&tty_ldisc_lock, flags);

tty_ldiscs[disc] = new_ldisc;

new_ldisc->num = disc;

new_ldisc->refcount = 0;

spin_unlock_irqrestore(&tty_ldisc_lock, flags);

return ret;

}

EXPORT_SYMBOL(tty_register_ldisc);


三、当然有注册,就有注销,只不过不常用。


/**

 * tty_unregister_ldisc-unload a line discipline

 * @disc: ldisc number

 * @new_ldisc: pointer to the ldisc object

 *

 * Remove a line discipline from the kernel providing it is not

 * currently in use.

 *

 * Locking:

 * takes tty_ldisc_lock to guard against ldisc races

 */



int tty_unregister_ldisc(int disc)

{

unsigned long flags;

int ret = 0;



if (disc < N_TTY || disc >= NR_LDISCS)

return -EINVAL;



spin_lock_irqsave(&tty_ldisc_lock, flags);

if (tty_ldiscs[disc]->refcount)

ret = -EBUSY;

else

tty_ldiscs[disc] = NULL;

spin_unlock_irqrestore(&tty_ldisc_lock, flags);

return ret;

}

EXPORT_SYMBOL(tty_unregister_ldisc);


四:和上层tty连接


每个终端设备都有个struct tty_struct结构体,可能被包含在一个更大的结构体中。


/*

 * Where all of the state associated with a tty is kept while the tty

 * is open.  Since the termios state should be kept even if the tty

 * has been closed --- for things like the baud rate, etc --- it is

 * not stored here, but rather a pointer to the real state is stored

 * here.  Possible the winsize structure should have the same

 * treatment, but (1) the default 80x24 is usually right and (2) it's

 * most often used by a windowing system, which will set the correct

 * size each time the window is created or resized anyway.

 * - TYT, 9/14/92

 */


struct tty_operations;

struct tty_struct {

int magic;

struct kref kref;

struct tty_driver *driver;

const struct tty_operations *ops;

int index;

/* The ldisc objects are protected by tty_ldisc_lock at the moment */

struct tty_ldisc ldisc; 与具体线程的关联在这

struct mutex termios_mutex;

spinlock_t ctrl_lock;

/* Termios values are protected by the termios mutex */

struct ktermios *termios, *termios_locked;

struct termiox *termiox; /* May be NULL for unsupported */

char name[64];

struct pid *pgrp; /* Protected by ctrl lock */

struct pid *session;

unsigned long flags;

int count;

struct winsize winsize; /* termios mutex */

unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1;

unsigned char low_latency:1, warned:1;

unsigned char ctrl_status; /* ctrl_lock */

unsigned int receive_room; /* Bytes free for queue */


struct tty_struct *link;

struct fasync_struct *fasync;

struct tty_bufhead buf; /* Locked internally */

int alt_speed; /* For magic substitution of 38400 bps */

wait_queue_head_t write_wait;

wait_queue_head_t read_wait;

struct work_struct hangup_work;

void *disc_data;

void *driver_data;

struct list_head tty_files;



#define N_TTY_BUF_SIZE 4096



/*

* The following is data for the N_TTY line discipline.  For

* historical reasons, this is included in the tty structure.

* Mostly locked by the BKL.

*/

unsigned int column;

unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;

unsigned char closing:1;

unsigned short minimum_to_wake;

unsigned long overrun_time;

int num_overrun;

unsigned long process_char_map[256/(8*sizeof(unsigned long))];

char *read_buf;

int read_head;

int read_tail;

int read_cnt;

unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))];

int canon_data;

unsigned long canon_head;

unsigned int canon_column;

struct mutex atomic_read_lock;

struct mutex atomic_write_lock;

unsigned char *write_buf;

int write_cnt;

spinlock_t read_lock;

/* If the tty has a pending do_SAK, queue it here - akpm */

struct work_struct SAK_work;

struct tty_port *port;

};


关键字:linux 引用地址:linux串口终端驱动——s3c6410平台(三)

上一篇:linux串口终端驱动——s3c6410平台(二)
下一篇:linux串口驱动——s3c6410平台(一)

推荐阅读最新更新时间:2024-11-03 16:58

ARM-Linux移植之(四)——根文件系统构建
相关工具版本: busybox-1.7.0 arm-linux-4.3.2 linux-2.6.22 1.配置busybox并安装。 在我们的根文件系统中的/bin和/sbin目录下有各种命令的应用程序,而这些程序在嵌入式系统中都是通过busybox来构建的,每一个命令实际上都是一个指向busybox的链接,busybox通过传入的参数来决定进行何种命令操作。 1)配置busybox 解压busybox-1.7.0,然后进入该目录,使用makemenuconfig进行配置。这里我们这配置两项 一是在编译选项选择动态库编译,当然你也可以选择静态,不过那样构建的根文件系统会比动态编译的的大。 - Busybox Settings
[单片机]
瑞萨电子成为首家加入民用基础设施平台项目的半导体供应
全球领先的半导体解决方案供应商瑞萨电子株式会社(“瑞萨电子”,TSE:6723)今天宣布其已加入民用基础设施平台(CIP)项目。作为Linux基金会(一个支持Linux操作系统(OS)传播的非营利性组织)的合作项目,CIP于2016年4月推出,为民用基础设施系统的工业级开源软件(OSS,注1)提供基础层。从RZ/G系列开始,瑞萨电子计划开发一个针对工业应用的嵌入式平台,将合作项目中的工业级Linux操作系统引入工业应用的嵌入式平台。   Linux基金会首席运营官Mike Woster表示:“作为Linux基金会的活跃黄金会员和汽车级Linux(AGL)项目的白金会员,瑞萨电子为开源开发做出了巨大贡献。如今,瑞萨电子可将其行业领先
[半导体设计/制造]
gdbserver远程调试嵌入式linux应用程序方法
简介:嵌入式linux应用程序的开发一般都是在linux里面编写好代码,并用交叉编译器arm-linux-gcc编译好之后再下载到板子上运行。如果建立了远程调试(能够在PC机ubuntu中调试板子中的linux应用程序),这样对于开发程序是极其方便的。以下是摘自网络上的一些方法。其中加入了自己所遇到的一些问题,并提出了解决方法。 1、首先建立nfs文件系统,让PC机ubuntu上的文件系统这里假设路径为:/home/xxx/work/可以挂载到板子上去。方法可以见本博的另一篇文章。其中IP环境是PC机win7的IP为192.168.0.11(这个不重要,只要保证在同一个网段即可)。虚拟机中IP为:192.168.0.57。下位
[单片机]
ARM Linux系统中的用户栈与内核栈
在Linux系统上,一个进程有两种不同的栈,一种是用户栈,另一种是内核栈。 用户栈 用户栈就是应用程序直接使用的栈。如下图所示,它位于应用程序的用户进程空间的最顶端。 当用户程序逐级调用函数时,用户栈从高地址向低地址方向扩展,每次增加一个栈帧,一个栈帧中存放的是函数的参数、返回地址和局部变量等,所以栈帧的长度是不定的。 用户栈的栈底靠近进程空间的上边缘,但一般不会刚好对齐到边缘,出于安全考虑,会在栈底与进程上边缘之间插入一段随机大小的隔离区。这样,程序在每次运行时,栈的位置都不同,这样黑客就不大容易利用基于栈的安全漏洞来实施攻击。 用户栈的伸缩对于应用程序来说是透明的,应用程序不需要自己去管理栈,这是操作系统提供的功能。应用
[单片机]
ARM <font color='red'>Linux</font>系统中的用户栈与内核栈
ARM矩阵键盘设计及其linux驱动实现
  在嵌入式系统开发中,经常通过键盘来实现人机交互。本文介绍了一种直接利用ARM的I/O口扩展矩阵键盘的方法。同时以TQ2440开发板为例,对硬件电路连接和相应的linux驱动设计方法都作了详细说明。   1.引言   ARM微处理器已广泛应用于 工业控制 、消费类电子产品、通信系统等领域。矩阵键盘是一种常用的键盘形式,它将按键设计成M行N列,这样共需M+N根信号线,却可驱动M×N个按键,大大节约了I/O资源。本文介绍了一种利用TQ2440开发板的GPIO口扩展5×4矩阵键盘的方法,并将所有按键重新布局成手持终端的键盘形式,方便操作。   2.硬件设计   本设计扩展5行4列的矩阵键盘,如图1所示。其中行线ROW1-ROW
[电源管理]
ARM矩阵键盘设计及其<font color='red'>linux</font><font color='red'>驱动</font>实现
基于ARM-Linux的无线气象数据通信系统的设计与实现
自动气象站数据采集器一般基于单片机或PC/104总线控制器设计,具有与PC兼容性好、功耗低、体积紧凑等特点,然而如何设计出功能强大,网络传输功能强的自动气象站数据采集器,满足现代气象检测的要求,是一个值得研究的课题。 文中基于ARM微处理器和Linux操作系统平台,借助前端无线传感器网络的数据输入,利用嵌入式Qt的开发优势并设计数据通信格式,完成无线气象数据通信系统的设计,实现了数据的可靠传输。为天气预报、科学研究、气象灾害预警等提供实时的气象观测数据。 1 无线气象数据通信系统的基本组成 如图1所示,无线气象数据通信系统主要由无线传感器网络节点、协调器、数据通信器(数据通信器以S3C2440AL为核心)、远程服务器等组成,
[单片机]
基于ARM-<font color='red'>Linux</font>的无线气象数据通信系统的设计与实现
Uncompressing Linux... done, booting the kernel
今天用主线Linux内核移植到MINI6410,主线内核2.6.37.1基本已经支持了MINI6410的板子,所以移植到能够启动起来的阶段很简单,但是在移植的时候还是出现了一个比较常见的问题: MINI6410 # bootm 0x50008000 ## Booting kernel from Legacy Image at 50008000 ... Image Name: Linux-2.6.37.1 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3800644 Bytes = 3.6 MiB Load Address: 50008000
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved