星期五, 十二月 28, 2007

gcc核心扩展

===========================
Linux 内核使用的 GNU C 扩展
===========================

GNC CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,
这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。本文把
支持 GNU 扩展的 C 语言称为 GNU C。

Linux 内核代码使用了大量的 GNU C 扩展,以至于能够编译 Linux 内核的唯一编
译器是 GNU CC,以前甚至出现过编译 Linux 内核要使用特殊的 GNU CC 版本的情
况。本文是对 Linux 内核使用的 GNU C 扩展的一个汇总,希望当你读内核源码遇
到不理解的语法和语义时,能从本文找到一个初步的解答,更详细的信息可以查看
gcc.info。文中的例子取自 Linux 2.4.18。

语句表达式
==========

GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出
现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本
只能在复合语句中使用。例如:

++++ include/linux/kernel.h
159: #define min_t(type,x,y) \
160:         ({ type __x = (x); type __y = (y); __x window_clamp, tcp_full_space(sk));

复合语句的最后一个语句应该是一个表达式,它的值将成为这个语句表达式的值。
这里定义了一个安全的求最小值的宏,在标准 C 中,通常定义为:

#define min(x,y) ((x) " "%s:%d", filename, line)

使用 ## 的原因是处理 arg 不匹配任何参数的情况,这时 arg 的值为空,GNU
C 预处理器在这种特殊情况下,丢弃 ## 之前的逗号,这样

    pr_debug("success!\n")

扩展为

    printk("" "success!\n")

注意最后没有逗号。

标号元素
========

标准 C 要求数组或结构变量的初使化值必须以固定的顺序出现,在 GNU C 中,通
过指定索引或结构域名,允许初始化值以任意顺序出现。指定数组索引的方法是在
初始化值前写 '[INDEX] =',要指定一个范围使用 '[FIRST ... LAST] =' 的形式,
例如:

+++++ arch/i386/kernel/irq.c
1079: static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };

将数组的所有元素初使化为 ~0UL,这可以看做是一种简写形式。

要指定结构元素,在元素值前写 'FIELDNAME:',例如:

++++ fs/ext2/file.c
41: struct file_operations ext2_file_operations = {
42:         llseek:         generic_file_llseek,
43:         read:           generic_file_read,
44:         write:          generic_file_write,
45:         ioctl:          ext2_ioctl,
46:         mmap:           generic_file_mmap,
47:         open:           generic_file_open,
48:         release:        ext2_release_file,
49:         fsync:          ext2_sync_file,
50 };

将结构 ext2_file_operations 的元素 llseek 初始化为 generic_file_llseek,
元素 read 初始化为 genenric_file_read,依次类推。我觉得这是 GNU C 扩展中
最好的特性之一,当结构的定义变化以至元素的偏移改变时,这种初始化方法仍然
保证已知元素的正确性。对于未出现在初始化中的元素,其初值为 0。

Case 范围
=========

GNU C 允许在一个 case 标号中指定一个连续范围的值,例如:

++++ arch/i386/kernel/irq.c
1062:                         case '0' ... '9': c -= '0'; break;
1063:                         case 'a' ... 'f': c -= 'a'-10; break;
1064:                         case 'A' ... 'F': c -= 'A'-10; break;

    case '0' ... '9':

相当于

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':

声明的特殊属性
==============

GNU C 允许声明函数、变量和类型的特殊属性,以便手工的代码优化和更仔细的代
码检查。要指定一个声明的属性,在声明后写

    __attribute__ (( ATTRIBUTE ))

其中 ATTRIBUTE 是属性说明,多个属性以逗号分隔。GNU C 支持十几个属性,这
里介绍最常用的:

* noreturn

属性 noreturn 用于函数,表示该函数从不返回。这可以让编译器生成稍微优化的
代码,最重要的是可以消除不必要的警告信息比如未初使化的变量。例如:

++++ include/linux/kernel.h
47: # define ATTRIB_NORET  __attribute__((noreturn)) ....
61: asmlinkage NORET_TYPE void do_exit(long error_code)
        ATTRIB_NORET;

* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)

属性 format 用于函数,表示该函数使用 printf, scanf 或 strftime 风格的参
数,使用这类函数最容易犯的错误是格式串与参数不匹配,指定 format 属性可以
让编译器根据格式串检查参数类型。例如:

++++ include/linux/kernel.h?
89: asmlinkage int printk(const char * fmt, ...)
90:         __attribute__ ((format (printf, 1, 2)));

表示第一个参数是格式串,从第二个参数起根据格式串检查参数。

* unused

属性 unused 用于函数和变量,表示该函数或变量可能不使用,这个属性可以避免
编译器产生警告信息。

* section ("section-name")

属性 section 用于函数和变量,通常编译器将函数放在 .text 节,变量放在
.data 或 .bss 节,使用 section 属性,可以让编译器将函数或变量放在指定的
节中。例如:

++++ include/linux/init.h
78: #define __init          __attribute__ ((__section__ (".text.init")))
79: #define __exit          __attribute__ ((unused, __section__(".text.exit")))
80: #define __initdata      __attribute__ ((__section__ (".data.init")))
81: #define __exitdata      __attribute__ ((unused, __section__ (".data.exit")))
82: #define __initsetup     __attribute__ ((unused,__section__ (".setup.init")))
83: #define __init_call     __attribute__ ((unused,__section__ (".initcall.init")))
84: #define __exit_call     __attribute__ ((unused,__section__ (".exitcall.exit")))

连接器可以把相同节的代码或数据安排在一起,Linux 内核很喜欢使用这种技术,
例如系统的初始化代码被安排在单独的一个节,在初始化结束后就可以释放这部分
内存。

* aligned (ALIGNMENT)

属性 aligned 用于变量、结构或联合类型,指定变量、结构域、结构或联合的对
齐量,以字节为单位,例如:

++++ include/asm-i386/processor.h
294: struct i387_fxsave_struct {
295:         unsigned short  cwd;
296:         unsigned short  swd;
297:         unsigned short  twd;
298:         unsigned short  fop;
299:         long    fip;
300:         long    fcs;
301:         long    foo;
......
308: } __attribute__ ((aligned (16)));

表示该结构类型的变量以 16 字节对齐。通常编译器会选择合适的对齐量,显示指
定对齐通常是由于体系限制、优化等原因。

* packed

属性 packed 用于变量和类型,用于变量或结构域时表示使用最小可能的对齐,用
于枚举、结构或联合类型时表示该类型使用最小的内存。例如:

++++ include/asm-i386/desc.h
51: struct Xgt_desc_struct {
52:         unsigned short size;
53:         unsigned long address __attribute__((packed));
54: };

域 address 将紧接着 size 分配。属性 packed 的用途大多是定义硬件相关的结
构,使元素之间没有因对齐而造成的空洞。

当前函数名
==========

GNU CC 预定义了两个标志符保存当前函数的名字,__FUNCTION__ 保存函数在源码
中的名字,__PRETTY_FUNCTION__ 保存带语言特色的名字。在 C 函数中,这两个
名字是相同的,在 C++ 函数中,__PRETTY_FUNCTION__ 包括函数返回类型等额外
信息,Linux 内核只使用了 __FUNCTION__。

++++ fs/ext2/super.c
98: void ext2_update_dynamic_rev(struct super_block *sb)
99: {
100:         struct ext2_super_block *es = EXT2_SB(sb)->s_es;
101:
102:         if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV)
103:                 return;
104:
105:         ext2_warning(sb, __FUNCTION__,
106:                      "updating to rev %d because of new feature flag, "
107:                      "running e2fsck is recommended",
108:                      EXT2_DYNAMIC_REV);

这里 __FUNCTION__ 将被替换为字符串 "ext2_update_dynamic_rev"。虽然
__FUNCTION__ 看起来类似于标准 C 中的 __FILE__,但实际上 __FUNCTION__
是被编译器替换的,不象 __FILE__ 被预处理器替换。

内建函数
========

GNU C 提供了大量的内建函数,其中很多是标准 C 库函数的内建版本,例如
memcpy,它们与对应的 C 库函数功能相同,本文不讨论这类函数,其他内建函数
的名字通常以 __builtin 开始。

* __builtin_return_address (LEVEL)

内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址,参数
LEVEL 指定在栈上搜索框架的个数,0 表示当前函数的返回地址,1 表示当前函数
的调用者的返回地址,依此类推。例如:

++++ kernel/sched.c
437:                 printk(KERN_ERR "schedule_timeout: wrong timeout "
438:                        "value %lx from %p\n", timeout,
439:                        __builtin_return_address(0));

* __builtin_constant_p(EXP)

内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数
EXP 的值是常数,函数返回 1,否则返回 0。例如:

++++ include/asm-i386/bitops.h
249: #define test_bit(nr,addr) \
250: (__builtin_constant_p(nr) ? \
251:  constant_test_bit((nr),(addr)) : \
252:  variable_test_bit((nr),(addr)))

很多计算或操作在参数为常数时有更优化的实现,在 GNU C 中用上面的方法可以
根据参数是否为常数,只编译常数版本或非常数版本,这样既不失通用性,又能在
参数是常数时编译出最优化的代码。

* __builtin_expect(EXP, C)

内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表
达式 EXP 的值,C 的值必须是编译时常数。例如:

++++ include/linux/compiler.h
13: #define likely(x)       __builtin_expect((x),1)
14: #define unlikely(x)     __builtin_expect((x),0)
++++ kernel/sched.c
564:         if (unlikely(in_interrupt())) {
565:                 printk("Scheduling in interrupt\n");
566:                 BUG();
567:         }

这个内建函数的语义是 EXP 的预期值是 C,编译器可以根据这个信息适当地重排
语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中
断上下文是很少发生的,第 565-566 行的目标码可能会放在较远的位置,以保证
经常执行的目标码更紧凑。

Read More...

以用户空间权限访问GPIO

在将Linux系统移植到相关板子上后,我们面临的就是一个编程问题了。开发板上有很多资源是可以和内核中的驱动对应的,比如我们今天要介绍的,最简单的,gpio。

首先你需要用在/dev下mknod xgpio:

crw-rw-rw- 1 root root 10, 185 Jun 1 13:59 /dev/xgpio

下面就是具体访问gpio的示例:


To write to the channel change the call:
ioctl(fgpio,XGPIO_IN,&sGpioData); to ioctl(fgpio,XGPIO_OUT,&sGpioData);

#include
#include
#include
#include

#include

main(){

int fgpio =0;
struct xgpio_ioctl_data sGpioData;
/* {
__u32 device;
__u32 mask;
__u32 data;
}*/

sGpioData.device=0; /* N=0,1,2,3-> GPIO DEV NR 2*N (Lower 32 bit part)
2*N+1 (Upper 32 bit part)*/
sGpioData.mask=0xffffffff;
sGpioData.data=0×55555555;

fgpio = open (”/dev/xgpio”,O_RDWR);

if( fgpio != -1){
ioctl(fgpio,XGPIO_IN,&sGpioData);//pointer here to xgpio_ioctl_data
printf(”Dip Swich readout 0x%X\n”,sGpioData.data);
}
else
printf(”Can not open GPIO\n”);

close(fgpio);
}// end main

Read More...

星期一, 十二月 24, 2007

gentoo下的kde4

Read More...

键盘的改革

Read More...

星期一, 十二月 17, 2007

关于u8 u16 u32 以及arm中的长度问题。『转』

首先先来看看2个程序,第一次看会死人的。
#include <stdio.h>
struct test{
unsigned int a1;
unsigned char a2;
unsigned short a3;
unsigned char a5;
unsigned int a4;
};

int main(void)
{
printf("a:%d\n",sizeof(struct test));
return 0;
}
显示16
----------
#include <stdio.h>
struct test{
unsigned int a1;
unsigned char a2;
unsigned char a5;
unsigned short a3;
unsigned int a4;
};

int main(void)
{
printf("a:%d\n",sizeof(struct test));
return 0;
}
显示12
----------
为什么呢??
因为:
unsigned char a2;
unsigned short a3;
unsigned char a5;
主要是因为u16和u8的排列问题
--------------
如果char后面跟的是u16,那char就是2字节存储了。
后面的char是单字节,但是a5后面是int,所以a5就当4字节存储了。
u8就是unsigned char
那么u16=unsigned short
u32=unsigned int了呵呵。
short 16
char 8
int 32
在arm和32bit的intel中是这么定义的。
我晕,还要管哪家公司定义的。
结构体中的排列问题 是编译器的原因还是什么?
是 cpu架构和编译器共同作用
---------------------------------------
好了,我们回头看那个程序。
第一个:
4+2+2+4+4=16
4(unsigned char)+2(unsigned char因为后面的16、2个字节,所以变了)+2(unsigned short)+4(unsinged char因为后面的32、4个字节所以变了)+4(unsigned int)=16
第二个:
4+1+1+2+4=12
就没怎么变。(ps: 还不知道为什么这个就没有8--〉16变成2字节,或许不用吧, 下午再问)
在这里谢谢id=思想者的老兄了。呵呵。这么本质的问题都有。厉害。

Read More...

星期三, 十二月 12, 2007

gcc的组件和软件工具

gcc安装的各个部分
 部分            描述
c++        gcc的一个版本,默认语言设置为c++,而且在连续的时候自动包含标准c++库。这和g++一样
ccl        实际的c编译程序
cclplus        实际的c
++编译程序
collect2               在不使用GNU链接程序的系统上,有必要运行collect2来产生特定的全局初始化代码
(例如c++的构造函数和析构函数)
configure               GCC源代码树根目录中的一个脚本,用于设置值和创建GCC编译程序必须的make程序的描述文件
crt0
.o        这个初始化和结束代码是为每个系统定制的,而且也被编译进该文件,该文件然后会被连接到每个可执行文件中来执行必要的启动和终止程序。
cygwinl
.dll    windows的共享库提供的API,模拟UNIX系统调用。
f77        该驱动程序可用于编译Fortran
f77l        实际的Fortran编译程序。
g
++        gcc的一个版本,默认语言设置为c++,而且在链接的时候自动包含标准c++库,这和c++一样
gcc        该驱动程序等同于执行编译程序和链接程序以产生必要的输出
gcj        该驱动程序用于编译java
gnatl        实际的Ada编译程序
gnatbind               一种工具,用于执行Ada语言的绑定
gnatlink               一种工具,用于执行Ada语言的绑定
jcl        实际的java编译程序
libgcc        该库包含的例程被作为编译程序的一部分,是因为它们可被链接到实际的可执行程序中。它们是特殊的例程,链接到可执行程序,来执行基本的任务,例如浮点运算。这些库中的例程通常都是平台相关的。
libgcj        运行时库包含所有的核心Java类
libobjc        对所有Objective
-c程序都必须的运行时的库。
libstdc
++               运行时库,包括定义为标准语言一部分的所有的c++类和函数                
                    
[b]gcc使用的工具[/b
[
b工具    [/b]     [b说明[/b
addr2line               给出一个可执行文件的内部地址,addr2line使用文件中的调试信息将地址翻译成源代码文件名和行号。该程序是binutils包的一部分
ar        这是一个程序,可通过从文档中增加、删除和析取文件来维护库文件。通常使用该工具是为了创建和管理链接程序使用的目标库文档。该程序是binutils包的一部分。
as        GNU汇编器。实际上他是一组汇编器,因为它可以被编译或能够在各个不同平台上工作。
autoconf              产生的shell脚本自动配置源代码包去编译某个特定版本的UNIX
c
++filt        程序接受被c++编译程序转换过的名字(不是被重载的),而且将该名字翻译成初始形式。该程序是binutils包的一部分
f2c        是Fortran到c的翻译程序。不是GCC的一部分。
gcov        gprof使用的配置工具,用来确定程序运行的时候哪一部分耗时最大
gdb        GNU调试器,可用于检查程序运行时的值和行为
GNATS        GNU的调试跟踪系统
(GNU Bug Tracking System)。一个跟踪GCC和其他GNU软件问题的在线系统。
gprof        该程序会监督编译程序的执行过程,并报告程序中各个函数的运行时间,可以根据所提供的配置文件来优化程序。该程序是binutils包的一部分。
ld        GNU链接程序。该程序将目标文件的集合组合成可执行程序。该程序是binutils包的一部分。
libtool        一个基本库,支持make程序的描述文件使用的简化共享库用法的脚本。
make        一个工具程序,它会读makefile脚本来确定程序中的那个部分需要编译和链接,然后发布必要的命令。它读出的脚本
(叫做makefile或Makefile)定义了文件关系和依赖关系。
nlmconv        将可重定向的目标文件转换成NetWare可加载模块
(NetWare Loadable Module NLM)。该程序是binutils包的一部分。
nm        列出目标文件中定义的符号,该程序是binutils包的一部分。
objcopy        将目标文件从一种二进制格式复制或翻译到另外一种。该程序是binutils包的一部分
objdump        显示一个或多个目标文件中保存的多种不同信息
.该程序是binutils包的一部分。
ranlib        创建的添加到ar文档的索引。该索引被ld使用来定位库中的模块。        该程序是binutils包的一部分。
ratfor        Ratfor预处理程序可由GCC激活,但不是标准GCC发布版的一部分。
size        列出目标文件中每个部分的名字和尺寸。该程序是binutils的一部分。
strings        浏览所有类型的文件,析取出用于显示调试所需的信息。        该程序binutils包的一部分。
veg        Ratfor浏览器从文本中读取信息,并以图标形式显示它们。而vcg工具并不是GCC发布的一部分,但
-dv选项可被用来产生vcg可以理解的优化数据的格式
windres        window资源文件编译程序,该程序是binutils包的一部

Read More...

星期一, 十二月 10, 2007

用注册表加载,卸载GDI++

打开regedit,浏览到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows,修改AppInit_DLLs的值,将其中的gdi++.dll相关的去掉即可。

或者:


代码:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
"AppInit_DLLs"=""
保存为一个reg文件,例如remove.reg,双击它也可以,但要注意,如果你安装了WB之类的,一并解决掉了。

Read More...

s3c2410 _spi概述

概况:

S3C2410X的连续外围设备接口(SPI)能连接电路实现连续数据传递。S3C2410X包含2SPI,,每个都分别有两个8位转移寄存器用于数据的传输和接收。在一个SPI进行数据传递时,同步传送数据并连续输出数据。在某一频率的8位连续数据由它相应的通讯控制寄存器设置所决定。假如你只发送数据,接收数据就能设为哑元。反之,如果你只想接收数据,你应该发送设为哑元'1'数据。

S3C24104个与SPI传输有关的I/O信号引脚:SCK(SPICLK01)MISO(SPIMISOO1)数据线,MOSISPIMOSIO1)和低电平有效的/SS(nSS01)引脚(输入)

特点

SPI协议(Ver.2.11)兼容

8位移位寄存器输出

8位移位寄存器接收

8位预分频逻辑

查询,中断,DMA传输模式

 

 

SPI操作

采用SPI接口, S3C2410X可发送/接收与外部设备同步的8位数据。一个串行时钟线与两条用来移位和采样信息的数据线同步。 SPI为主机时,发送频率可以通过为SPPREn寄存器设置合适的值来控制。你可以通过调整波特率数据寄存器的值来修改它的频率。当SPI为从机时,其它的主机提供时钟。当编程者向SPTDATn寄存器写字节数据时,SPI的收/发将会同时开始。在其它情况下,在向SPTDATn寄存器写入字节数据时要把nSS激活。

 

编辑程序

 

当向SPTDATn寄存器写入字节时,如果ENSCKSPCONn被设置的话,SPI就开始传输

你可以使用一上典型的程序来操作一个SPI卡。

编程SPI模式,基本遵循这些基本步骤:

1.       设置波特率寄存器(SPPREn

2.       设置SPCONn以选择合适的SPI模式。

3.        写数据0xFFSPTDATn10次以初始化MMCSD卡。.

4.       设置GPIO引脚使其具有nSS功能,低电平时使MMCSD卡有效。

5.       发送数据:检查发送准备樗是否为1,如果为1 的话就开始向SPTDATn写数据。

6.       接收数据(1):SPCONn TAGD 位禁用 = 正常模式

    :向SPTDATn 0xFF,然后测试REDY,再从读缓存中读取数据。

7.       接收数据:SPCONnTAGD 能用 = 自动接收垃圾数据模式。

    :测试REDY,然后从读缓存中读取数据。

8.       设置GPIO引脚使其具有nSS功能,高电平时使MMCSD卡有效。

 

 

通过DMA发送的步骤

1.       SPI的配置为DMA模式

2.       DMA合适设置

3.       SPI请求DMA服务

4.       DMASPI发送一个字节数据.

5.        SPI向卡里发送数据

6.       返回到步骤3直到DAM计数变为0

7.       SMOD位把SPI设置为中断或查询模式

 

通过DMA接收的步骤

1.       SPI设置为DMASMOD位开始,并且设置TAGD.

2.       全适配置 DMA

3.       SPI从卡里接收一字节数据

4.       SPI请求DMA服务

5.       DMASPI接收数据

6.        自动的向SPIDATn写数据0xFF

7.        回到步骤4DAM计数变为0

8.       SMOD位把SPI配置为查询模式,并且清TAGD

9.       如果SPSTAnREDY 标志被设置,就读取最后的字节数据

 

:

总接收的数据 = DAM TC +在查询模式下的最后值.

DAM接收的第一个数据是哑元,所以使用者可以忽略它

SPI 从机接收模式和B模块

 

如果SPI从机接收模式有效和SPI模块被设成B模块,SPI操作将会失败。

READY信号这一内部信号将在SPI_CNT达到0之前变成高电平。因此,在DMA模式中,DATA_READ信号应该在最后一个数据结束之前产生。

注意

1)      DMA模式:这种模式不能在SPI从机接收模式和B模块下使用。

2)      查询模式:在SPI从机接收模式和B模块下DATA_READ信号应该推迟SPICLK的一个相位。

3)      中断模式:在SPI从机接收模式和B模块下DATA_READ信号应该推迟SPICLK的一个相位。

SPI特殊寄存器

SPI控制寄存器

SPI状态寄存器

SPI引脚控制寄存器

如果SPI系统使能时,除nSS引脚外的其它引脚的方向通过SPCONnMSTR位来控制。nSS引脚的方向总是输入。

SPI为主机时,nSS引脚用来检查由SPPINENMUL位提供的多主机错误信号,另一个GPIO应该选择从机。

如果SPI被设置为从机,nSS引脚奖被一个主机选择为从机。

SPIMISOSPIMOSI数据引脚用来发送和接收串行数据。当SPI为主机时,SPIMISO是数据输入引脚,SPIMOSI是数据输出引脚,SPICLKSCK)是时钟输出线。当SPI为从机时,这些引脚执行相反的功能。在多主机系统中,SPICLKSCK)、SPIMOSISPIMISO将被分别的配置在一个体系中。

当其它的SPI设备作为从机选择S3C2410 SPI为从机时,一个主机SPI可以发出一个多主机错误信号。当这个信号被探测到,将会立刻发生下面所说的事情。但是如果你想探测到这种信号的话必须事先设置SPPINnENMUL位。

 

1.       SPCONnMSTR位被强制为0来启动从机模式。

2.       SPSTAnMULF标志位被置位,一个SPI中断会产生。

概况:

S3C2410X的连续外围设备接口(SPI)能连接电路实现连续数据传递。S3C2410X包含2SPI,,每个都分别有两个8位转移寄存器用于数据的传输和接收。在一个SPI进行数据传递时,同步传送数据并连续输出数据。在某一频率的8位连续数据由它相应的通讯控制寄存器设置所决定。假如你只发送数据,接收数据就能设为哑元。反之,如果你只想接收数据,你应该发送设为哑元'1'数据。

S3C24104个与SPI传输有关的I/O信号引脚:SCK(SPICLK01)MISO(SPIMISOO1)数据线,MOSISPIMOSIO1)和低电平有效的/SS(nSS01)引脚(输入)

特点

SPI协议(Ver.2.11)兼容

8位移位寄存器输出

8位移位寄存器接收

8位预分频逻辑

查询,中断,DMA传输模式

 

 

SPI操作

采用SPI接口, S3C2410X可发送/接收与外部设备同步的8位数据。一个串行时钟线与两条用来移位和采样信息的数据线同步。 SPI为主机时,发送频率可以通过为SPPREn寄存器设置合适的值来控制。你可以通过调整波特率数据寄存器的值来修改它的频率。当SPI为从机时,其它的主机提供时钟。当编程者向SPTDATn寄存器写字节数据时,SPI的收/发将会同时开始。在其它情况下,在向SPTDATn寄存器写入字节数据时要把nSS激活。

Read More...