第一篇:linux0.11系统调用原理及实验总结
Linux0.11系统调用原理及实验总结
系统调用的原理
1.1 概述
系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数库中再通过int 0x80进行系统调用。
所以,系统调用过程是这样的:
应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int 0x80完成系统调用并返回。
另外一种访问内核的方式是直接添加一个系统调用,供自己的应用程序使用,这样就不再使用库函数了,变得更为直接,效率也会更高。
1.2 相关的数据结构
在说具体的调用过程之前,这里先要说几个数据结构。
1.2.1 系统调用函数表
系统调用函数表sys_call_table是在sys.h中定义的,它是一个函数指针数组,每个元素是一个函数指针,它的值是各个系统提供的供上层调用的系统函数的入口地址。也就是说通过查询这个表就可以调用软中断0x80所有的系统函数处理函数。
1.2.2 函数指针偏移宏
这是一系列宏,它们的定义在unistd.h中,基本形式为#define _NR_name value,name为系统函数名字,value是一个整数值,是name所对应的系统函数指针在sys_call_table中的偏移量。
1.2.3 系统调用宏
系统调用宏_syscalln(type,name)在内核的unistd.h文件中定义的,对它展开就是: type name(参数列表){ 调用过程; }; 其中,n为参数个数,type为函数返回值类型,name为所要调用的系统函数的名字。在unistd.h中共定义了4个这样的宏(n从0到3),也就是说,0.11核中系统调用最多可带3个参数。那么下面就说这个宏干了什么,也就是说上面的那个“调用过程”是怎么样的呢?在这个宏中嵌入了汇编代码,做的工作就是int 0x80,其中将字符串“_NR_”和name连接,组成一个宏并将这个宏的值,也就是被调用的系统函数在sys_call_table中偏移量送到eax寄存器中;同时指明系统函数将来的返回值放到eax中。
1.3 系统调用处理过程
下面我再说一下系统调用的核心软中断int 0x80具体干了什么。这条指令会引起CPU的软件中断,cpu会根据中断号找到中断处理程序。这个中断处理程序是在System_call.s中。在中断处理程序的工作过程大致是这样的:
1.3.1 将寄存器ds,es,fs以及存有参数的edx,ecx,ebx入栈,再ds,es,指向内核段,fs指向用户段。
1.3.2 根据eax中的偏移值,在函数表sys_call_table中找到对应的系统函数指针(函数的入口地址)。并利用call指令调用系统函数,返回后,程序把返回值加入堆栈。
1.3.3 检查执行本次系统调用的进程的状态,如果发现由于某种原因原进程没处在就绪状态或者时间片到了,就会执行进程调度函数schedule()。1.3.4 通过执行这次调用的程序的代码选择符判断它是不是普通用户程序,如果是就调用信号处理函数。若不是就直接弹出栈内容,并返回 添加一个系统调用的实验
2.1 实验内容
在linux0.11版本中添加两个系统调用,并编写一个简单的应用程序测试它们。
第一个系统调用是iam(),其原型为:
intiam(const char * name);完成的功能是将字符串参数name的内容拷贝到内核中保存下来。要求name的长度不能超过23个字符。返回值是拷贝的字符数。如果name的字符个数超过了23,则返回“-1”,并置errno为EINVAL。
第二个系统调用是whoami(),其原型为:
intwhoami(char* name, unsigned int size);它将内核中由iam()保存的名字拷贝到name指向的用户地址空间中,同时确保不会对name越界访存(name的大小由size说明)。返回值是拷贝的字符数。如果size小于需要的空间,则返回“-1”,并置errno为EINVAL。
2.2 代码添加修改步骤
2.2.1 在unistd.h中添加系统调用接口
#define __NR_whoami 72 #define __NR_iam 73 intwhoami(void);intaim(void);
2.2.2 在exit.c文件中添加系统调用处理函数的实现
系统调用的函数可以在其他.c文件中添加或在新建文件中添加,只要编辑进image都是可以的,这里为了调试方便就在exit.c文件中添加了。
#define MAX 23 char N_MAX[26];
intsys_whoami(char* name, unsigned int size){ if(strlen(N_MAX)>size)return-EINVAL;
int i;
for(i=0;N_MAX[i]!=' ';i++){
put_fs_byte(N_MAX[i],&name[i]);}
returnstrlen(N_MAX);}
intsys_iam(char *name){
char c;charstr[100];memset(str,' ',sizeof(str));int i;
for(i = 0;i <= MAX;i++)
{ if((c=get_fs_byte(&name[i]))!=' ')
{ str[i] = c;
} else break;}
if((c!= ' ')||(i>MAX))
{ return-EINVAL;}
memset(N_MAX,' ',sizeof(N_MAX));
for(i=0;str[i]!=' ';i++){
N_MAX[i]=str[i];} return i;} 2.2.3 在system_call.s汇编代码中修改系统调用的个数
#If 0 nr_system_calls = 72 #else
nr_system_calls = 74 #endif
2.2.4 测试代码的编写test.c的代码如下:
#define __LIBRARY__ #include
int main(){ int a = 0;char bb[26] = “champion”;char cc[26] = “";
a = iam(bb);printf(”a=%d“, a);
a = whoami(cc,8);printf(”iam=%sn“,cc);return(1);} 系统调用相关代码的分析
3.1 初始化软件中断门。
3.1.1 函数调用层次
初始化软件中断门,就是把0x80软件中断的处理函数system_call挂载到中断向量表idt中,以确保发生软件中断时会运行system_call函数,这个函数在system_call.s实现。初始化的流程如下:
main()sched_init()set_system_gate(0x80, &system_call)_set_gate
3.1.2 初始化宏_set_gate的原型
/* 传入的四个参数说明如下:
gate_addr =&idt[0x80]软件中断门的地址。type= 15type为门类型 dpl = 3dpl为请求特权级
addr = &system_call = 0x7119通过查找system.map可以查到中断处理程序的地址 */
#define _set_gate(gate_addr,type,dpl,addr)__asm__(”movw %%dx,%%axnt“
”movw %0,%%dxnt“ ”movl %%eax,%1nt“ ”movl %%edx,%2nt“ : : ”i“((short)(0x8000+(dpl<<13)+(type<<8))), ”o“(*((char *)(gate_addr))), ”o“(*(4+(char *)(gate_addr))), ”d“((char *)(addr)),”a“(0x00080000))3.1.3 分析初始化宏_set_gate的实现
__asm__格式为嵌入式汇编的格式,分析可知代码有5个传入的参数%0,%1,%2,%3,%4如下: %0,立即数
”i“((short)(0x8000+(dpl<<13)+(type<<8)))这样,%%edx中高16位为addr的高16位,而低16位的P位为1(因为是0x8000),DPL位段为DPL(因为dpl<<3),而D位加上类型位段则为type(因为type<<8)其余各位皆为0
%1 是用内存地址,并且可以加偏移量 ”o“(*((char *)(gate_addr))), gate_addr =&idt[0x80]
%2 是用内存地址,并且可以加偏移量 ”o“(*(4+(char *)(gate_addr))), gate_addr =&idt[0x80]
%3,edx做为参数 ”d“((char *)(addr)), &system_call = 0x7119 edx = &system_call = 0x7119
%4,eax做为参数 ”a“(0x00080000))eax = 0x00080000
__asm__格式为嵌入式汇编的格式,分析可知四条命令含义如下:
”movw %%dx,%%axnt“
先将%%dx的低16位移入%%ax的低16位
这样,在%eax中就形成了所需要的中断门的第一个长整数,其高16位为_KERNEL_CS,而低16位为addr的低16位。
”movw %0,%%dxnt“
字操作
16位操作,操作低16位,高16位已经有调用函数的地址.”movl %%eax,%1nt“
双字操作,为门的0--31位赋值
”movl %%edx,%2nt“
双字操作,为门的32--63位赋值
3.2 以_syscall1为例,分析系统调用入口宏的含义。
其中_syscall1是一个宏,在include/unistd.h中定义。将_syscall1(int,close,int,fd)进行宏展开,可以得到:
#define _syscall1(type,name,atype,a)type name(atype a){ long __res;__asm__ volatile(”int $0x80“ : ”=a“(__res): ”0“(__NR_##name),”b“((long)(a)));
if(__res >= 0)return(type)__res;errno =-__res;return-1;}
传入参数说明:
其中type表示系统调用的返回值类型,name表示该系统调用的名称,atype、a分别表示第1个参数的类型和名称;可以有n个系统调用的传入参数,它们的数目和_syscall后面的数字一样大。
调用接口宏含义说明:
它先将宏__NR_##name存入EAX,将参数fd存入EBX,然后进行0x80中断调用。调用返回后,从EAX取出返回值,存入__res,再通过对__res的判断决定传给API的调用者什么样的返回值。__NR_##name就是系统调用的编号,在include/unistd.h中定义;在上面的例子中,我们添加了两个自己的系统调用接口,如下:
#define __NR_whoami 72 #define __NR_iam 73
3.3 对_system_call函数的分析
处理流程图
处理流程分析 _system_call: cmpl $nr_system_calls-1,%eax # 调用号如果超出范围的话就在eax中置-1 并退出。jabad_sys_call push %ds # 保存原段寄存器值。push %es push %fs pushl %edx # ebx,ecx,edx中放着系统调用相应的C 语言函数的调用参数。pushl %ecx# push %ebx,%ecx,%edx as parameters pushl %ebx # to the system call movl $0x10,%edx# set up ds,es to kernel space mov %dx,%ds # ds,es指向内核数据段(全局描述符表中数据段描述符)。mov %dx,%es movl $0x17,%edx # fs points to local data space mov %dx,%fs# fs指向局部数据段(局部描述符表中数据段描述符)。
# 下面这句操作数的含义是:调用地址 = _sys_call_table + %eax * 4。参见列表后的说明。# 对应的C 程序中的sys_call_table在include/linux/sys.h中,其中定义了一个包括72 个 # 系统调用C 处理函数的地址数组表。call _sys_call_table(,%eax,4)pushl %eax# 把系统调用号入栈。
movl _current,%eax# 取当前任务(进程)数据结构地址。
# 下面查看当前任务的运行状态。如果不在就绪状态(state 不等于0)就去执行调度程序。# 如果该任务在就绪状态但counter值等于0,则也去执行调度程序。cmpl $0,state(%eax)# state jne reschedule cmpl $0,counter(%eax)# counter je reschedule
3.4 用户态和内核态之间的传递数据
在内核中主要提供了四个函数实现内核态和用户态的数据传递:copy_to_user(),copy_from_user(),get_fs_byte(),put_fs_byte();上面测试用例中使用的是对字节的操作get_fs_byte(),put_fs_byte()。
通过bochs环境如何验证系统调用
1.1 Bochs+Linux0.11调试环境建立。
可以分为两个部分的工作:搭建调试环境和Bochs命令的使用;这两部分网上资料较多,就不在此描述了。
1.2 测试程序的修改和添加方法。
1.2.1 使用mount命令访问文件系统hdc-0.11.img 要想把测试程序test.c运行起来,一定要放入文件系统才行,也就是一定要把test.c程序放进hdc-0.11.img中去才行,可以用如下的方法打开文件系统:
losetup /dev/loop1 hdc-0.11.img losetup-d /dev/loop1
losetup-o 512 /dev/loop1 hdc-0.11.img
mkdir/mnt/tempdir mount-t minix /dev/loop1 /mnt/tempdir
说明:用losetup的-d选项把hdc-0.11.img文件与loop1的关联解除,用losetup的-o选项,该选项指明关联的起始字节偏移位置。由上面分区信息可知,这里第1个分区的起始偏移位置是1 * 512 字节。
在把第1个分区与loop1重新关联后,我们就可以使用mount命令来访问其中的文件了。在对分区中文件系统访问结束后,最后请卸载和解除关联。umount /dev/loop1 losetup-d /dev/loop1 1.2.2 编译test.c测试程序
把测试程序放到/mnt/tempdir/user/root目录下,这样就可以任意修改test.c文件的内容,并可以把修改的内容保存到hdc-0.11.img文件系统中去了。
1.3 通过bochs调试观察,是如何把0x80的中断函数system_call的地址挂载上去的。1.3.1 通过添加do_nothing()函数,然后在此函数设置断点,可以查看0x80中断处理函数是如何放到中断向量表中去的。
加入调试辅助代码如下:
因为set_system_gate是一个宏,没有办法添加断点,所以就添加了一个函数do_nothing(),在此处设置断点,以方便观察后面宏的运行情况;并且加入了几个nop命令,以方便观察运行情况。
voidsched_init(void){ do_nothing();set_system_gate(0x80,&system_call);} 1.3.2 修改_set_gate宏如下,加入了nop命令,以便调试观察。
#define _set_gate(gate_addr,type,dpl,addr)__asm__(”nop nt“ ”nop nt“ ”nop nt“ ”nop nt“ ”movw %%dx,%%axnt“ ”movw %0,%%dxnt“ ”nop nt“ ”nop nt“ ”movl %%eax,%1nt“ ”movl %%edx,%2nt“ ”nop nt“ ”nop nt“ ”nop nt“ ”nop “ : : ”i“((short)(0x8000+(dpl<<13)+(type<<8))), ”o“(*((char *)(gate_addr))), ”o“(*(4+(char *)(gate_addr))), ”d“((char *)(addr)),”a"(0x00080000))
1.3.3 可以看到运行的效果如下:
在system.map中,看到do_nothing的线性地址是0x6c1d,可以在此处设置断点。
Figure 1设置断点
Figure 2程序运行到_set_gate宏
Figure 3查看此时寄存器中的数值
调试测试程序test.c和sys_whoami和sys_iam函数 1.4.1 调试系统调用处理函数sys_whoami和sys_iam. 在system.map文件中,找到编译kernel后,函数sys_whoami和sys_iam所在的线性地址。如下所示: 00008dba T sys_iam 00008e57 T sys_whoami 在bochs启动kernel后,在0x8dba和0x8e57处设置断点,然后运行test程序,就会进入系统调用处理函数,运行到设置的断点处,后面可以单步运行,以调试sys_whoami和sys_iam,达到测试系统调用的目的。
如下图所示: 1.4
1.4.2 在linux0.11的系统中编译运行test程序
在运行起来的linux0.11的系统中,通过make test命令编译test.c文件,使生产test应用。运行test程序后,iam()函数就会通过get_fs_byte()函数把“champion”字符串存入到内存中;
whoami()函数就会把前面存入到内存中的字符串取出,并且通过put_fs_byte()内核函数返回到用户层;并且打印出来。如下所示:
第二篇:嵌入式系统原理实验总结报告
嵌入式系统原理实验总结报告
车辆座椅控制系统实验
2014/5/23
嵌入式系统原理实验总结报告
一、技术性总结报告
(一)题目:车辆座椅控制系统实验
(二)项目概述:
1.为了实现车辆座椅控制的自动化与智能化。
2.方便用户通过智能手机与车载传感器之间的联动。3.使车辆作为当今物联网中重要的一个节点发挥作用。
4.通过车辆座椅控制系统实验实现对嵌入式系统原理课程的熟练掌握与对嵌入式系统原理知识的深化记忆。
5.加强本组学生对嵌入式系统原理的更深层次的理解与运用。
(三)技术方案及原理
本次试验分为软件、硬件两个部分。1.软件部分。
A.智能手机部分,包括通过智能手机对座椅的控制部分、手机所携带的身份信息部分。
本部分软件使用Java编写,其程序部分为: 主程序:
package com.example.seat;
import android.support.v7.app.ActionBarActivity;import android.support.v7.app.ActionBar;import android.support.v4.app.Fragment;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.os.Build;
import java.io.BufferedReader;import java.io.IOException;
import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.InetAddress;import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;
import android.view.KeyEvent;import android.view.View;import android.widget.Button;
public class MainActivity extends ActionBarActivity { private Button Up = null;private Button Left = null;private Button Dowm = null;private Button Right = null;private Socket socket = null;
private static final String HOST = “192.168.1.142”;
private static final int PORT = 10007;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControl();
}
private void initControl(){
Up =(Button)findViewById(R.id.button1);
Up.setOnClickListener(new ReceiverListener());
}
class ReceiverListener implements OnClickListener {
protected String line;
@Override
public void onClick(View v){
// TODO Auto-generated method stub
new Thread(){
@Override
public void run(){
try {
Socket socket = new Socket(HOST, PORT);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
line = br.readLine();
br.close();
} catch(UnknownHostException e){
// TODO Auto-generated catch block
e.printStackTrace();
} catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
}.start();
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
// Handle action bar item clicks here.The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();
if(id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
} } 界面代码:
package=“com.example.seat” android:versionCode=“1” android:versionName=“1.0” > android:name=“android.permission.ACCESS_NETWORK_STATE”/> android:minSdkVersion=“8” android:targetSdkVersion=“19” /> android:allowBackup=“true” android:icon=“@drawable/ic_launcher” android:label=“@string/app_name” android:theme=“@style/AppTheme” > android:name=“com.example.seat.MainActivity” android:label=“@string/app_name” >
host = '' port = 10007
pwm = PWM(0x6F, debug=True)
servoMin = 125 # Min pulse length out of 4096 , 0.5 servoMax = 575 # Max pulse length out of 4096 , 2.3
def setServoPulse(channel, pulse):
pulseLength = 1000000
# 1,000,000 us per second
pulseLength /= 60
# 60 Hz
print “%d us per period” % pulseLength
pulseLength /= 4096
# 12 bits of resolution
print “%d us per bit” % pulseLength
pulse *= 1000
pulse /= pulseLength
if(pulse>servoMax): pulse = servoMax
if(pulse pwm.setPWM(channel, 0, int(pulse)) pwm.setPWMFreq(60) # Set frequency to 60 Hz pwm.setPWM(0, 0, servoMax) if __name__ == '__main__': s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((host, port)) s.listen(3) print 'Server is running on port %d, press Ctrl-C to terminate it.' % port pulse_ud = 1.9 pulse_lr = 1.9 setServoPulse(0,pulse_ud) setServoPulse(1,pulse_lr) while True: clientsock, clientaddr = s.accept() clientfile = clientsock.makefile('rw', 0) ctrlinfo = clientfile.readline().strip() print 'Control info is %s.n' % ctrlinfo if ctrlinfo == “up”: pulse_ud += 0.1 elif ctrlinfo == “down”: pulse_ud-= 0.1 elif ctrlinfo == “left”: pulse_lr += 0.1 elif ctrlinfo == “right”: pulse_lr-= 0.1 else: print “ERRORn” setServoPulse(0,pulse_ud) setServoPulse(1,pulse_lr) clientfile.close() clientsock.close() 2.硬件部分。 对车载座椅控制部分发出的信息的接受、识别、执行部分。本次试验使用的硬件设备包括:智能手机一部、“树莓派”一台、小舵机两台、舵机驱动板一个、无线网卡一个、杜邦线若干、5V电源一个、无线路由器一个 智能手机 树莓派(外) 树莓派(内) 小舵机 舵机驱动板 无线网卡 杜邦线 5V电源 无线路由器 (四)实验流程及结果 1.打开智能手机上的控制软件。 2.向车载座椅控制台发送信息。(发送信息分别为上、下、左、右)3.车载座椅控制台接受、识别并执行信息。4.通过小舵机的动作验证该实验是否成功。(详细见视频) 二、工作进度自评表 本次试验完成。 本次试验计划分为三个阶段。 第一阶段:智能手机部分、车载座椅控制部分和硬件部分的分别完成。本阶段完成。 第二阶段:智能手机部分、车载座椅控制部分和硬件部分的整合阶段。本阶段完成。 第三阶段:车辆座椅控制系统实验的验收调试阶段。本阶段完成。 三、组内人员自评 本次试验打到预期的实验目的。虽然在实验进行过程中遇到了不少的麻烦,但是通过我们成员自身的努力学习掌握了实验所要求的知识。最后实验的成功与组员之间的互相帮助与紧密配合是分不开的。 四、个人学习心得 本人通过此次实验,对于嵌入式系统原理有了更加深层次的了解。对于设计嵌入式系统原理的实验也有了较为高程度的提高。为了以后更进一步的学习并掌握嵌入式系统打下了坚实的一步。对于了解车辆座椅控制的自动化与智能化;了解用户通过智能手机与车载传感器之间的联动;了解车辆作为当今物联网中重要的一个节点都发挥了重要作用。通过车辆座椅控制系统实验实现对嵌入式系统原理课程的熟练掌握与对嵌入式系统原理知识的深化记忆。加强本组学生对嵌入式系统原理的更深层次的理解与运用。 化工原理实验总结 化工原理是环境工程专业必修的一门极为重要的专业基础课,化工原理实验是学习、掌握和运用这门课程的重要环节。比起我们之前做的普通实验,化工原理实验更具工程特点,要求我们对理论知识的掌握也更加严格。通过化工原理及做实验的整个过程,我不仅学到了专业知识,在理解和巩固了理论知识的同时也积累了许多生活经验,了解到生活中我们所接触的普通事物的基本原理。 每次实验之前,在我们预习了教材的有关理论,理解了实验目的、原理及要求,了解了实验流程及操作步骤基础上,会先做仿真实验具体了解实验主要操作及过程,真正做实验时老师会及其细致的再将实验原理及实验所涉及的知识讲解一遍,同时具体的介绍实验流程、装置及主要设备的结构、测控元件及仪器仪表的使用方法,介绍实验操作步骤、数据测量和整理方法,最后,辅助我们对实验数据进行正确处理。这一整套流程,保证我们实验能够顺利进行,并能够对实验中发生的现象加以分析,从而找出原因加以解决。这种手脑结合的方式,启发和诱导了我们的思维,充分调动我们的参与意识和学习积极性,同时培养我们的学习兴趣,锻炼和培养了独立思考、分析问题和解决问题的能力,达到了高效学习的效果。 无论是化工原理课程学习中还是做实验过程中,老师都强调了伯努力方程的重要性,老师在讲到流体流动一章中的伯努利方程时,引导我们思考“人往高处走,水往低处流”的科学道理的基础上,思考着“水能不能由低处流向高处?能不能由低压容器流向高压容器呢?”。我们思维会使我们直接回答不会,但仔细思考,在无外界作用下确实不会,但如果这时把问题引到能量守恒上来,对流体做功使得流体具有能量再将能量转换成势能是完全可以的,这时又会想到引出流体的输送设备即“泵与风机”。老师在讲解原理时,将实际生活中与之紧密联系的现象,诸如飞机起飞、乒乓球的弧线球的产生与喷雾器原理等加以解释,强化我们对伯努力原理的理解,这样就可以在实际生活及科研过程中灵活地运用伯努力原理。在老师引导下,我懂得了不仅要考虑设备费及节能降耗,还要考虑产品产量与操作稳定性等问题,从而提炼一些工程观点。我们通过这种独立思考的方式,对问题产生浓厚的兴趣,从而产生急于找出问题答案和解决问题的心理状态,很好地培养思维能力和想象力。 这学期我们做了三个化工原理实验,每一次实验都有不足之处,理论知识的不完善导致对整个实验操作过程理解不够透彻,最后在分析实验结果时不能够准确分析出实验中所出现的问题并总结出结论,但每一次实验都比前一次实验有经验,做之前也会更注重理论知识的理解与掌握。流体流动阻力的测定实验中,我们主要研究影响流体阻力的因素,测定了在镀锌钢管、不锈钢管及突然扩大管中流体流动情况,从而推算出直管阻力和局部阻力,得出λ与Re的关系。同时联系实际我们也就懂得了泳衣,船头,模仿鲔鱼体形的核潜艇,流线型汽车的工作原理。在离心泵的性能测定实验中,不仅对离心泵的原理有了深入了解,更对离心泵的内部结构,叶轮,平衡孔,轴封装置等有了初步认识,同时知道了确定泵的最佳工作范围的方法。而传热实验更与我们生活实际密切相关。 “化工原理”是一门与生产和生活实际紧密联系的课程,其基本理论在实际生产、科研和生活中应用非常广泛。工程理论的重要性就体现在它的实用性,应用工程理论处理实际问题时,一定要明确工程理论的应用条件。因此,在学习过程中不仅要充分利用书本知识,而且应注意联系实际生活,注意将各种工程问题进行分类,培养抓住问题的本质,从根本上找出解决问题的思路、方法和步骤的能力。简单来说,化工原理是用直观的实例,来唤起联想的灵感,发挥我们的创新思维,所以学好化工原理大有益处。 , 化工原理实验论文 化工原理实验是化工原理课程中理论与实践相联系、相结合的重要教学环节之一。,其基本任务是巩固和加深对化工原理课程中基本理论知识的理解,通过实验操作和实验现象的观察,使学生掌握一定的基本实验技能。 本学期化工原理实验课堂上我们一共做了十个实验,分别为伯努利方程实验、流体流动形态的观察和测定、流体流动阻力的测定、离心泵特性曲线的测定、恒压过滤常数的测定、空气-蒸汽给热系数的测定、填料精馏塔实验、填料吸收塔的操作及吸收传质系数的测定、流化床干燥实验以及膜分离实验。 开始的时候,我并不是很明白许多实验仪器的使用方法以及如何通过实验验证理论知识,虽然每次实验前都会有预习,但是在没有真正接触到实验的时候还是会有一头雾水的感觉。课前老师的讲解对我来说十分重要,自己不明白的地方,在听老师讲解时有时便会豁然开朗。我知道如果不明白实验原理,不知道实验目的,我们是不会真正利用到实验的价值。 我认为做实验的过程是一个既快乐又充满理性知识的过程。就像书本上的知识跳跃了起来一样,不再那么枯燥无味,通过自己的亲手操作和认真计算将原理进行证明的过程我们仿佛能够体会以前科学家的智慧结晶,自己也可以身临其境的体会学习化工原理的快乐。 例如流体阻力的测定实验旨在让我们了解流体流动阻力的测定方法,确定摩擦系数与雷诺准数的关系以及局部阻力由于一开始对这个实验不是很了解,使得流体的流量过小达不到实验预期效果。 恒压过滤实验时,第一组实验因为没有正确装好板框导致实验重来,让我们从中吸取教训:实验一定要严格遵守实验步骤的每一个要求,否则可能前功尽弃。 还有吸收实验中,我们了解了填料塔吸收装置的基本结构及操作方法,这个实验中,我们组的进出口二氧化碳含量出现了问题。在实验的过程中,我们遇到过挫折,一开始心里还是很着急,有点不知所措,但后来我调整了心态,理性分析实验过程问题,才能使实验顺利完成。 化工原理实验最重要的就是将理论付诸实践,平时我们上化工原理课的时候,只能通过老师的讲解,自己的想象了解知识,许多时候我们甚至不能明白为什么就能有这样的结论。而化工原理实验就提供给我们一个平台,一个能更深入了解化工原理知识、更锻炼自己动手能力、在学习上更加丰富的平台。我们可以通过实验锻炼动手能力,团队合作能力,不再读死书,死读书。 化工原理实验从各个方面锻炼了我们的能力。 首先,预习是帮助理解实验原理,了解实验内容,操作步骤以及实验注意事项以利于完成实验达到较好的教学效果。在每次实验前,我们都会写预习报告,了解实验目的,清楚实验原理,实验仪器,这培养了我们自学的能力; 其次,正确进行实验操作,是成功作好实验的关键。在实验过程中,我们需要耐心,细心,认真的完成实验步骤,掌握实际操作和掌握化工实验的基本技能,培养观察实验现象,测定化工参数的能力,掌握用计算机读数和数据记录。 最后就是实验过后的数据处理和回答思考题,这也是完成一个实验的最后一个阶段,是整个实验最终能够出结果的重要阶段,通过数据处理我们可以跟所学知识进行比较,进而提高到能应用实验误差和误差理论分析、解决化工原理实际问题,得出较正确的结论。看是否能够验证试验原理,实验做得是否成功,而思考题更是将我们引入了一个深入思考实验的阶段,让我们对实验更加清楚。 学习化工原理实验课程,可以在学习化工原理课程的基础上,进一步理解一些比较典型的已被或将被广泛应用的化工过程与设备的原理和操作,巩固和深化化工原理的理论知识,将所学的化工原理等化学化工的理论知识去解决实验中遇到的各种实际问题,同时学习在化工领域内如何通过实验获得新的知识和信息,这学期的化工原理实验课我收获很多,了解了典型化工过程和化工设备结构的特点 也逐步对化工原理产生了更加浓厚的兴趣。 化工原理实验总结 本学期化工原理实验课堂上我们一共做了三个实验,分别为流体阻力的测定、离心泵特性曲线的测定、传热试验。 开始的时候,我并不是很明白许多实验仪器的使用方法以及如何通过实验验证理论知识,虽然每次实验前都会有预习,但是在没有真正接触到实验的时候还是会有一头雾水的感觉。课前老师的讲解对我来说十分重要,自己不明白的地方,在听老师讲解时有时便会豁然开朗。我知道如果不明白实验原理,不知道实验目的,我们是不会真正利用到实验的价值。 我认为做实验的过程是一个既快乐又充满理性知识的过程。就像书本上的知识跳跃了起来一样,不再那么枯燥无味,通过自己的亲手操作和认真计算将原理进行证明的过程我们仿佛能够体会以前科学家的智慧结晶,自己也可以身临其境的体会学习化工原理的快乐。 流体阻力的测定实验旨在让我们了解流体流动阻力的测定方法,确定摩擦系数与雷诺准数的关系以及局部阻力。离心泵特性曲线实验旨在让我们了解离心泵的基本操作,为以后的泵与风机课程提供了入门的基础,另外就是测定单机离心泵在一定转速下的特性曲线。由于一开始对这两个实验不是很了解,使得流体的流量过小达不到实验预期效果。第二次实验是传热试验,这个实验是为了让我们掌握传热系数、给热系数、导热系数的测定方法。并比较汽—水套管、裸管和保温管的单位管长下的传热速率,掌握热电偶测温原理。一开始我们做得很顺利,但过程中仪器遇到了一些问题,只得使用另一组仪器。在实验的过程中,我们遇到过挫折,一开始心里还是很着急,有点不知所措,但后来我调整了心态,理性分析实验过程问题,才能使实验顺利完成。 化工原理实验最重要的就是将理论付诸实践,平时我们上化工原理课的时候,只能通过老师的讲解,自己的想象了解知识,许多时候我们甚至不能明白为什么就能有这样的结论。而化工原理实验就提供给我们一个平台,一个能更深入了解化工原理知识、更锻炼自己动手能力、在学习上更加丰富的平台。我们可以通过实验锻炼动手能力,团队合作能力,不再读死书,死读书。 学习化工原理实验课程,可以在学习化工原理课程的基础上,进一步理解一些比较典型的已被或将被广泛应用的化工过程与设备的原理和操作,巩固和深化化工原理的理论知识,将所学的化工原理等化学化工的理论知识去解决实验中遇到的各种实际问题,同时学习在化工领域内如何通过实验获得新的知识和信息,这学期的化工原理实验课我收获很多,了解了典型化工过程和化工设备结构的特点 也逐步对化工原理产生了更加浓厚的兴趣。第三篇:化工原理实验总结
第四篇:化工原理实验总结
第五篇:化工原理实验总结