接受到上层的汇编指令,会触发底层的物理芯片电路(例如用VHDL生成的电路)把真正的数据发出去。
发送数据时也有规律,数据只会在时钟的上升沿发送。
物理芯片帮助我们实现了数据的传送,传送数据会按照特定的协议规范传输。(比如起始位,终止位等等)
寄存器是位于物理电路中的触发器。这些触发器的某些位和物理芯片的其他部件(如片选,与门)进行相连,把某位设置成0/1能够影响到电路的通与断。
因此设置某个寄存器的某位能够对芯片的工作模式/方式起作用
读写特定的内存单元。
汇编指令有MOV,高级语言中除c/C++外没有其他编程语言可以直接访问绝对地址的能力。
c语言是借助了指针所具有的绝对地址单元内容的读写能力。
unsigned char * p =(unsigned char *)0xf000ff00
函数实际上也就是一直地址。
typedef void (*lpFunction) ( ); /* 定义一个无参数、无返回类型的 */
/* 函数指针类型 */
lpFunction lpReset = (lpFunction)0xF000FFF0; /* 定义一个函数指针,指向*/
/* CPU启动后所执行第一条指令的位置 */
lpReset(); /* 调用函数 */
中断服务程序(ISR)
中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序 (ISR),类似于__interrupt、#program interrupt等。当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码
硬件驱动模块
(1)中断服务程序ISR
(2)硬件初始化
a.修改寄存器,设置硬件参数(如UART应设置其波特率,AD/DA设备应设置其采样速率等)
b. 将中断服务程序入口地址写入中断向量表
/* 设置中断向量表 */
m_myPtr = make_far_pointer(0l); /* 返回void far型指针void far * */
m_myPtr += ITYPE_UART; /* ITYPE_UART: uart中断服务程序 */
/* 相对于中断向量表首地址的偏移 */
*m_myPtr = &UART _Isr; /* UART _Isr:UART的中断服务程序 */
(3)设置CPU针对该硬件的控制线
如果控制线可作PIO(可编程I/O)和控制信号用,则设置CPU内部对应寄存器使其作为控制信号
设置CPU内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)
(4) 提供一系列针对该设备的操作接口函数。例如,对于LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块则需提供获取时间、设置时间等函数。
system_call (~/linux/arch/i386/kernelentry.S)
#define __NR_oldstat 18 ~/linux/include/asm-i386/unistd.h"
VHDL函数会根据时序返回一个值,如果函数觉得时序乱了,就会返回硬件错误,对于结果来说,就是出现了一些意想不到的结果。程序可能接着执行,也可能直接死机
在汇编级的编程,返回值会放到通用寄存器。 EERROR/EINVALID并不是说硬件有问题了,只是在内核定义的一个错误参数。
在C语言中通用寄存器的值又会返回一个更通俗的值。
一个完整的硬件会给我我们提供如下的咚咚
1)硬件电路(时序图)
2)与硬件电路对应的指令集
3)硬件提供相应的编译器(编译加链接)
阅读(2293) | 评论(0) | 转发(0) |