0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

英创信息技术精简ISA总线Linux编程–Part1

英创信息技术 来源:英创信息技术 作者:英创信息技术 2020-02-07 11:19 次阅读

精简ISA总线接口是一种8-bit宽度的双向并行扩展总线,其特点是地址数据分时复用8-bit总线,加上4条总线控制信号,即可实现对外部数据的快速读写。若再使能一条总线时钟信号(共13条信号),就可实现高达10MB/s的数据传输。精简ISA总线作为英创主板的特色功能之一,在ESM6802、ESM7000、ESM7100、ESM335x等多款型号中均有配置。

对精简ISA总线接口的应用编程,将通过3个部分分别加以介绍。本文是第一部分,主要介绍ISA总线的访问模式,以及最基本的总线数据读写。第二部分介绍由应用程序启动基于DMA的数据块读写。采用DMA方式实现数据库读写,可有效降低CPU的负载率。第三部分介绍ISA扩展硬件触发DMA数据传输的方法,该方法主要面向工业控制领域的高速数据采集。由于采用硬件触发的DMA传输机制,使得前端的高速AD单元不再采用昂贵的高速SRAM做数据缓冲,从而使采集单元的成本大幅度下降。该方法可实现高达5MB/s(每秒5兆字节)以上的数据采集率。

ISA总线信号定义如下:

信号及说明 PIN# 信号及说明
RESET_B,硬件复位 1 2 ISA_ADVn,地址锁存控制信号
ISA_AD0,地址数据总线,LSB 3 4 ISA_AD4,地址数据总线
ISA_AD1,地址数据总线 5 6 ISA_AD5,地址数据总线
ISA_AD2,地址数据总线 7 8 ISA_AD6,地址数据总线
ISA_AD3,地址数据总线 9 10 ISA_AD7,地址数据总线,MSB
MSLn,支持多模块挂接总线 11 12 ISA_WEn,数据写控制信号
GPIO9,可选作为IRQ 13 14 ISA_RDn,数据读控制信号
GPIO8,可选作为IRQ 15 16 ISA_CSn,片选控制信号
GPIO25,可选作为IRQ 17 18 VDD_5V0,+5V供电
GPIO24 / ISA_BCLK,同步时钟ISA_BCLK 19 20 GND,电源信号地

本文以下部分,将以ESM7000 Linux平台为例,介绍具体的编程方法。

ISA总线操作模式

精简ISA总线的宽度只有8-bit,因此它的地址寻址范围也只有8-bit,即0x00 – 0xFF。ISA总线的驱动程序支持应用程序使用不同的地址范围,来区别不同的访问类型。根据ISA地址可有如下6种类型:

模式 offset ISA总线操作
0 0x0000 … 0x00FF 异步总线周期,CPU操作
1 0x1000 … 0x10FF 异步总线周期,MemCpy方式DMA,固定端口地址
2 0x2000 … 0x20FF 异步总线周期,外部信号触发方式DMA,固定端口地址
3 0x3000 … 0x30FF 同步总线周期,CPU操作,要求ISA端口地址16字节对齐
4 0x4000 … 0x40FF 同步总线周期,MemCpy方式DMA,同步译码端口
5 0x5000 … 0x50FF 同步总线周期,外部信号触发方式DMA,同步译码端口

ISA总线的异步总线周期是指每个总线周期读写一个字节,只需用到ISA最基本的12条信号线;而同步总线周期则需要使用总线时钟信号(共13条信号线),可实现一个总线周期读写4个字节。在《在英创工控主板上实现高速工控数据采集》一文中有对异步总线周期时序和同步总线周期时序较详细的介绍。

由iMX7DSDMA(Smart DMA)控制器特性决定,ESM7000可支持的ISA总线操作类型如下:

模式 offset ISA总线读操作
0 0x0000 … 0x00FF 异步总线周期,CPU读,inc仅对本模式有效
3 0x3000 … 0x30FF 同步总线周期,CPU读,要求ISA端口地址16字节对齐
4 0x4000 … 0x40FF 同步总线周期,MemCpy方式DMA读,同步译码端口
5 0x5000 … 0x50FF 同步总线周期,外部信号触发方式DMA读,同步译码端口
模式 offset ISA总线写操作
0 0x0000 … 0x00FF 异步总线周期,CPU写,inc仅对本模式有效
3 0x3000 … 0x30FF 同步总线周期,CPU写,要求ISA端口地址16字节对齐
4 0x4000 … 0x40FF 同步总线周期,MemCpy方式DMA写,同步译码端口

同步总线周期主要用于数据的高速传送,因此采用固定数据端口。数据端口的译码则采用直接识别同步总线周期的方法,而不再采用对总线地址译码的方法。异步总线周期则主要用于扩展电路单元内各寄存器的控制。

采用DMA进行ISA总线数据传送的目的,是为了降低高速传送大量数据时的CPU开销,使系统在进行高速数据采集的同时,还能进行其他的必要操作。MemCpy方式的DMA是指软件线程启动DMA,然后该线程挂起等待DMA操作完成。在多线程环境中,其他线程即可在DMA执行过程中得以并行运行。MemCpy方式DMA的具体情况将在《精简ISA总线编程– Part 2》中介绍。硬件触发DMA,为低成本实现高速数据采集提供了技术手段,将在《精简ISA总线编程– Part 3》中介绍相关的采集时序和程序实现。

表格中的offset项,是指在程序设计中使用的数据结构struct isa_transfer的成员,其结构如下:

structisa_transfer
{
void *rx_buf; /* != NULL: buffer for bus read */
void *tx_buf; /* != NULL: buffer for bus write */
unsigned len; /* buffer length in byte */
unsigned offset; /* offset,port address on isa bus */
unsigned inc; /* = 0: fixed offset, = 1: offset+1 after r/w */
};

每一个总线周期的操作只能是读或写,因此在isa_transfer结构中只能有一个buffer指针不为NULL。

ISA总线访问API

对ISA总线硬件端口的基本访问方法,包含在isa_api_v3.cpp文件中,如下所示:

#include
#include
#include
#include
#include
#include
#include"em335x_drivers.h"
unsignedchar *isa_base = NULL;
unsignedintmap_size = 4096;
// return >= 0: return file handle
// return < 0: return failed code
intisa_open()
{
intfd;
fd = open("/dev/em_isa", O_RDWR);
if(fd< 0)
{
returnfd;
}
isa_base = (unsignedchar*)mmap(0,map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (isa_base == MAP_FAILED) {
printf("%s mmap failed\n", __func__);
isa_base = NULL;
close(fd);
return -1;
}
returnfd;
}
intisa_close(intfd)
{
if(isa_base != NULL) {
munmap(isa_base, map_size);
isa_base = NULL;
}
returnclose(fd);
}
// offset: port address in isa bus
unsignedcharisa_read(intfd, unsignedint offset)
{
unsignedcharval_b;
int rc;
offset&= 0xff;
if(isa_base != NULL) {
unsignedshortintval_w;
val_w = *((unsignedshortint*)(isa_base + (offset << 1)));
val_b = (unsignedchar)(val_w& 0xff);
returnval_b;
}
val_b = offset;
rc = read(fd, &val_b, sizeof(unsignedchar));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
returnval_b;
}
// offset: port address in isa bus
voidisa_write(intfd, unsignedint offset, unsignedcharval_b)
{
unsignedshortintval_w;
int rc;
offset&= 0xff;
if(isa_base != NULL) {
val_w = val_b;
*((unsignedshortint*)(isa_base + (offset << 1))) = val_w;
return;
}
val_w = ((offset & 0xff) << 8) | val_b;
rc = write(fd, &val_w, sizeof(unsignedshortint));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
}
// offset: port address in isa bus
unsignedshortintisa_read16(intfd, unsignedint offset)
{
unsignedshortintval_w;
int rc;
// 2-byte alignment is required for offset
offset&= 0xfe;
if(isa_base != NULL) {
unsignedintval;
val = *((unsignedint*)(isa_base + (offset << 1)));
val_w = (unsignedshortint)((val>> 8) | (val& 0x00ff));
returnval_w;
}
val_w = (unsignedshortint)offset;
rc = read(fd, &val_w, sizeof(unsignedshortint));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
returnval_w;
}
// offset: port address in isa bus
voidisa_write16(intfd, unsignedint offset, unsignedshortintval_w)
{
unsignedintval;
intrc;
// 2-byte alignment is required for offset
offset&= 0xfe;
if(isa_base != NULL) {
val = val_w;
val = ((val<< 8) & 0x00ff0000) | (val& 0x000000ff);
*((unsignedint*)(isa_base + (offset << 1))) = val;
return;
}
val = (offset << 16) | val_w;
rc = write(fd, &val, sizeof(unsignedint));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
}
intisa_read_buf(intfd, structisa_transfer *tp)
{
int rc;
rc = read(fd, tp, sizeof(structisa_transfer));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
returnrc;
}
intisa_write_buf(intfd, structisa_transfer *tp)
{
int rc;
rc = write(fd, tp, sizeof(structisa_transfer));
if(rc< 0)
{
// read error
printf("%s failed %d\n", __func__, rc);
}
returnrc;
}

函数isa_open(..)和isa_close(..)是打开关闭ISA驱动的设备节点。为了提高应用程序访问ISA硬件寄存器的速度,ISA驱动实现了mmap功能,使isa_read(..)、isa_write(..)、isa_read16(..)和isa_write16(..)这4个函数可在用户空间直接操作ISA总线上的硬件寄存器,大大提高了代码的执行速度。注意若在多个线程中均有调用isa_api_v3.cpp的函数时,需要加互斥锁,保证对硬件资源操作的完整性。

CPU字节/字读写

函数isa_write(fd, 0x40, 0x55)是向地址为0x40的寄存器写入单个字节0x55,对应的总线时序为:

时序图显示了8位总线的地址/数据复用,地址需利用ADV#信号锁存。

函数isa_read(fd, 0x40)是从地址为0x40的寄存器读取单个字节,对应的总线时序为:

在上述时序中,ISA总线悬空,没有接具体的外围设备,因此由于分布电容的作用,在数据时段总线继续保持前面输出的地址0x40,读取的数据也会是0x40。若此时有外围设备输出数据至总线上,该数据则会被系统读取。

函数isa_write16(fd, 0x40, 0xaa55)是向地址为0x40的字寄存器写入16-bit字0xaa55,对应的总线时序为:

从时序图可见,16-bit数据写被分成两个连续的总线周期,其中低位字节0x55写入地址0x40寄存器,高位字节0xaa写入地址0x41寄存器。为了尽可能缩短2个周期的间隔,要求地址必须是偶对齐。

函数isa_read16(fd, 0x40)是从地址为0x40的字寄存器读取16-bit字,对应的总线时序为:

同样由于悬空总线的分布电容的作用,读取的数据会是0x4140。

CPU数据块读写

为了提高数据传输速度,对数据块操作,推荐采用同步总线周期。在ESM7000 Linux版本中,每个同步总线周期可传送4个字节。为了进一步加快数据块的传送,在驱动中使用了ARMv7的汇编块指令来支持16字节以上的数据传输。因此强烈建议数据块传输长度选择为16字节的整倍数,其数据端口占用16个ISA地址,即只对高4位地址译码。

进行数据块读写需要用到structisa_transfer传递相关参数。以下是执行32字节数据块写的代码,写入地址为0x3040。顺序的数据可方便时序的观察。

unsignedchargbuf[64 * 1024];
unsignedint i, value;
structisa_transfer t;
unsignedchar *pBuf8;
// write data block
memset(&t, 0, sizeof(structisa_transfer));
t.offset = 0x3040;
t.len = 32;
t.tx_buf = gbuf;
// fill data
value = 0x55; // initial value
pBuf8 = (unsignedchar*)t.tx_buf;
for(i = 0; i
*pBuf8 = (unsignedchar)(value + i);
pBuf8++;
}
isa_write_buf(fd, &t);

对应的总线时序说明如下:

上图可见,32个字节分成了8个总线周期完成,大致的总线速率为13MB/s。展开上述时序可看到:

总线上的数据0x55、0x59、…... 0x6D、0x71是每个总线周期CPU送出的第一个数据,保持3个时钟节拍,所以可在示波器中显示出来。进一步展开可看到:

ISA扩展单元可根据上述时序来支持高速的同步总线周期读写逻辑电路,其要点包括:

●每个周期的第一个BCLK下降沿ADV#有效,标志同步周期的开始,之后连续7个BCLK下降沿后同步周期结束。

●第一个总线周期地址为输入地址,之后每个总线周期的地址+4,按16模循环。因此要求数据端口占用16个ISA地址。

●BCLK频率30MHz,从第5个上升沿开始锁存数据,连续4个数据。没有BCLK时输出的数据没有意义,不影响正常的数据传输。

以上是对精简ISA总线基本读写的介绍,有兴趣的客户可与英创公司技术联系,索取测试代码源码。技术支持邮箱:support@emtronix.com。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11225

    浏览量

    208906
  • 嵌入式主板
    +关注

    关注

    7

    文章

    6085

    浏览量

    35210
收藏 人收藏

    评论

    相关推荐

    中科达荣获2024年软件和信息技术服务优秀企业

    及前百家企业”名单。中科达凭借非凡的技术实力与持续的创新能力,成功入选“2024年度软件和信息技术服务竞争力百强企业”以及“2024年软件和信息技术服务优秀企业”。
    的头像 发表于 10-30 11:44 379次阅读

    Linux应用编程的基本概念

    Linux应用编程涉及到在Linux环境下开发和运行应用程序的一系列概念。以下是一些涵盖Linux应用编程的基本概念。
    的头像 发表于 10-24 17:19 183次阅读

    国产化背景下的工控主板发展现状

    ,是信息技术应用创新产业的简称,于2016年“信工委会”(信息技术应用创新工作委员会)提出,目的就是要推动我们国内软硬件关键技术的研发
    的头像 发表于 09-21 16:15 329次阅读

    加速鲲鹏落地!拓维信息迁移工具荣获鲲鹏原生开发技术认证

    认证。图/拓维·数据库适配中间件取得鲲鹏原生开发N认证在数字化时代的大潮中,信战略作为国家推动信息技术应用创新、保障信息安全与自主可控的关键举措,其重要性日益凸显
    的头像 发表于 09-10 08:03 389次阅读
    加速鲲鹏落地!拓维<b class='flag-5'>信息</b>信<b class='flag-5'>创</b>迁移工具荣获鲲鹏原生开发<b class='flag-5'>技术</b>认证

    梯度科技入选2023年信息技术应用创新解决方案名单

    日前,工业和信息化部网络安全产业发展中心(工业和信息化部信息中心)在天津举办2024信息技术应用创新发展大会暨解决方案应用推广大会。会上正式公布了2023年
    的头像 发表于 09-09 16:29 387次阅读

    中软国际信服务助力大连信产业发展

    为进一步激发大连本地信产业生态的活力与潜力,搭建一个高效、开放的交流平台。由大连软件行业协会携手大连市信息技术应用创新综合服务中心主办,中软国际协办的,2024年大连市信息技术应用创新产业发展大会
    的头像 发表于 08-27 16:49 802次阅读

    Linux是做什么用的?

    ,进行软件开发、系统管理和网络管理等工作。 5、学习和教育:Linux是一个开源的操作系统,提供了大量的学习资源和教育机会。许多学校和教育机构使用Linux来教授计算机科学和信息技术相关的课程。 总之,
    发表于 04-28 15:40

    翼辉信息入选2023年信息技术应用创新解决方案名单

    近日,2023 年(第五届)信息技术应用创新解决方案公布遴选名单,历经资格初审、技术中评、区域评议、终评预审,翼辉以“面向工业领域嵌入式操作系统 SylixOS 解决方案”,成功在全国优秀方案中脱颖而出,入选典型解决方案名单。
    的头像 发表于 04-28 11:37 524次阅读
    翼辉<b class='flag-5'>信息</b>入选2023年<b class='flag-5'>信息技术</b>应用创新解决方案名单

    光庭信息荣膺武汉市侨届“科之星”称号

    4月2日,武汉市侨联十一届五次全委(扩大)会议隆重召开,武汉光庭信息技术股份有限公司(简称“光庭信息”)凭借其在科技创新领域的突出贡献,被授予“科之星”荣誉称号。
    的头像 发表于 04-07 10:25 381次阅读

    股份今日登陆科

    山东中软件商用中间件股份有限公司(以下简称“中股份”)近日在上海证券交易所科板成功上市,标志着这家国内知名的民营软件和信息技术服务企业正式进入资本市场,迎来全新的发展机遇。
    的头像 发表于 03-13 14:19 495次阅读

    龙芯中科三项信方案入围工信部2023年信息技术应用创新应用示范案例名单

    近日,工业和信息化部通报了2023年信息技术应用创新解决方案征集遴选结果,本次共评选出典型解决方案173个、应用示范案例83个、单项创新案例64个。
    的头像 发表于 03-07 16:45 856次阅读
    龙芯中科三项信<b class='flag-5'>创</b>方案入围工信部2023年<b class='flag-5'>信息技术</b>应用创新应用示范案例名单

    RX78M组 EtherCAT ETG.5003示例程序固件信息技术

    电子发烧友网站提供《RX78M组 EtherCAT ETG.5003示例程序固件信息技术.pdf》资料免费下载
    发表于 02-21 14:22 1次下载
    RX78M组  EtherCAT ETG.5003示例程序固件<b class='flag-5'>信息技术</b>

    软通动力与捷技术签订战略合作协议

    近日,软通动力信息技术(集团)股份有限公司(以下简称“软通动力”)与宁波捷技术股份有限公司(以下简称“捷技术”)正式签订战略合作协议,并
    的头像 发表于 02-03 16:35 1083次阅读

    PCB企业力三期项目顺利投产

    近日,PCB企业四川力电子科技股份有限公司三期(载板厂和特种板厂)顺利投产。通过这个项目,力公司成功地将业务范围从单一的普通通孔多层板扩展到了高端的IC载板、MiniLED基板
    的头像 发表于 01-15 14:20 570次阅读

    TQ3568开发平台Android11修改开机动画

    logo 图片的信息,需要怎么显示。作者的 desc.txt,如下所示: 480 271 3 p 1 0 part0 p 0 0 part1 480 271 这两个数字代表图片的像素
    发表于 12-07 13:45