星期二, 三月 13, 2007

JBoss Seam 安全一点通

介绍
Seam框架内嵌了安全控制功能,能达到对业务方法和页面层面的控制。Seam安全机制是建立在JAAS的基础之上的,能够完美支持验证和授权。
Seam的安全机制在应用时分为两种模式:
--简单模式,支持验证服务和简单的基于角色的安全检测功能。
--高级模式,除了具备简单模式的功能外,还增加了使用JBoss Rules进行的基于规则的安全检测功能。
其中简单模式可以应用于大部分对安全没有特殊要求的场合,例如,需要通过角色来限定登陆用户访问的页面和执行的动作。
而高级模式主要应用于需要根据上下文状态或复杂的业务规则来进行安全检测的场合。
当使用高级模式的时候,Seam框架需要以下工具的支持(简单模式不需要):
drools-compiler-3.0.5.jar
drools-core-3.0.5.jar
commons-jci-core-1.0-406301.jar
commons-jci-janino-2.4.3.jar
commons-lang-2.1.jar
janino-2.4.3.jar
stringtemplate-2.3b6.jar
antlr-2.7.6.jar
antlr-3.0ea8.jar

为了使用基于Web的安全检测,jboss-seam-ui.jar必须被包含到WAR包中,并且要如下配置faces-config.xml:
《application》
《view-handler》org.jboss.seam.ui.facelet.SeamFaceletViewHandler《/view-handler》
《/application》

实现登陆验证
× 在components.xml中配置验证方法:
《components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-1.2.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-1.2.xsd
http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-1.2.xsd"
http://jboss.com/products/seam/security http://jboss.com/products/seam/security-1.2.xsd"》

《security:identity authenticate-method="#{authenticator.authenticate}"/》

《/components》
表达式#{authenticator.authenticate} 指定了authenticator验证器中的验证方法,当调用authenticator验证器的login时是就会执行验证方法。

× 实现验证逻辑
@Name("authenticator")
public class Authenticator {
@In EntityManager entityManager;

public boolean authenticate() {
try
{
User user = (User) entityManager.createQuery(
"from User where username = :username and password = :password")
.setParameter("username", Identity.instance().getUsername())
.setParameter("password", Identity.instance().getPassword())
.getSingleResult();

if (user.getRoles() != null)
{
for (UserRole mr : user.getRoles())
Identity.instance().addRole(mr.getName());
}

return true;
}
catch (NoResultException ex)
{
FacesMessages.instance().add("Invalid username/password");
return false;
}

}

}
注解@Name("authenticator")把本类注册为Seam框架中的验证器,Identity.instance().getUsername()用来获取用户名称,Identity.instance().getPassword()用来获取用户输入的密码,Identity.instance().addRole()用于为经过验证的用户添加角色。

× 实现登陆页面
《div》
《h:outputLabel for="name" value="Username"/》
《h:inputText id="name" value="#{identity.username}"/》
《/div》

《div》
《h:outputLabel for="password" value="Password"/》
《h:inputSecret id="password" value="#{identity.password}"/》
《/div》

《div》
《h:commandButton value="Login" action="#{identity.login}"/》
《/div》
identity.login()方法用于验证用户,如果需要退出系统则调用 #{identity.logout}。

× 异常处理
当登陆验证失败或者用户权限不足时系统会抛出异常,为了不向用户暴露错误信息需要对pages.xml做以下异常重定向配置:
《pages》

...

《exception class="org.jboss.seam.security.NotLoggedInException"》
《redirect view-id="/login.xhtml"》
《message》You must be logged in to perform this action《/message》
《/redirect》
《/exception》

《exception class="org.jboss.seam.security.AuthorizationException"》
《end-conversation/》
《redirect view-id="/security_error.xhtml"》
《message》You do not have the necessary security privileges to perform this action.《/message》
《/redirect》
《/exception》

《/pages》

× 登陆后重定向
考虑以下场景,当用户访问受保护的资源时,系统会跳转到登陆页面要求用户登陆,当用户通过验证后,需要返回到登陆页面以前的受保护页面。
配置pages.xml实现未登录用户访问受保护页面时跳转到登陆页面:
《pages login-view-id="/login.xhtml"》

《page view-id="/members/*" login-required="true"/》

...

《/pages》

配置components.xml实现登陆后跳转:
《event type="org.jboss.seam.notLoggedIn"》
《action expression="#{redirect.captureCurrentView}"/》
《/event》

《event type="org.jboss.seam.postAuthenticate"》
《action expression="#{redirect.returnToCapturedView}"/》
《/event》

使用容器JAAS配置
如果需要使用容器提供的JAAS控制而不是Seam内置的SeamLoginModule,那么需要在components.xml配置文件中指定jaasConfigName属性,例如:
jaas-config-name="other"/>

授权
Seam为实现对Components(组件)、component method(组件方法) 和 pages(页面)的访问控制内置了很多的安全特性。提示:如果要使用高级模式请按照上面的配置启用高级模式。

核心概念
Seam框架提供的各种授权机制都是建立于一个前提概念之上的,那就是“系统中的每一个用户都会被授予角色和(或者)权限”,正是通过判断用户所具有的角色和(或者)权限能否满足被使用资源的声明,授权才准确地得以实行。其中,角色代表了一个组或者是类别的概念,被授予角色的用户可能会拥有访问多个资源的多个权限,角色代表一个权限集。而权限是单一的,是作用于单个资源上的一个动作。虽然仅仅使用权限也可以实现授权,但角色的引入大大的方便了授权的实现和管理。在表示方法上,角色仅仅通过一个名词来表示,例如,”管理员“,”编辑“,”拟稿人“,”仓库管理员“等等,而权限需要一个名词动词对来表达,例如,“客户:新增”,“客户:删除”,“产品:查询”等等。

组件的安全控制
在Seam中,注解@Restrict被用于声明安全检测。
Seam可以提供在类或者方法级别的安全检测,如果同时声明了类和方法级别的安全检测,那么方法级别优先而类级别被忽略。如果在一个组件类上应用了@Restrict,相当于对类中的每个方法都应用@Restrict。如果方法执行时发生了安全检测失败,作为约定,Identity.checkRestriction()会抛出一个异常。

一个空@Restrict注解代表了对一个由组件类名称和方法名称组合而成的权限进行隐式检测,例如:
@Name("account")
public class AccountAction {
@Restrict public void delete() {
...
}
}
即是代表了对权限“account:delete”进行检测相当于@Restrict("#{s:hasPermission('account','delete',null)}")显式检测。
再看另一个例子:
@Restrict @Name("account")
public class AccountAction {
public void insert() {
...
}
@Restrict("#{s:hasRole('admin')}")
public void delete() {
...
}
}
组件”account“在类级别启用了隐式安全检测,因此如果”account“内部的方法没有覆盖@Restrict声明的话都必须执行隐式权限检测,比如方法”insert“需要执行相当于@Restrict("#{s:hasPermission('account','insert',null)}")的权限检测,而方法”delete“因为声明了方法级别的@Restrict所以它将执行显式的@Restrict("#{s:hasRole('admin')}")角色检测。
注意s:hasPermission()和s:hasRole()都是表达式函数,对它们的调用会委派到Identity的对应方法。这些表达式函数可以在任意的表达式中使用,非常方便。
因为是表达式,@Restrict注解可以引用Seam上下文中任意的对象,这在需要对特定的对象实例进行安全检测时是非常方便的,例如:
@Name("account")
public class AccountAction {
@In Account selectedAccount;
@Restrict("#{s:hasPermission('account','modify',selectedAccount)}")
public void modify() {
selectedAccount.modify();
}
}
在执行modify方法时会去Seam的上下文中查找”selectedAccount“对象,并传递其引用到Identity的hasPermission(),这样就可以判断用户是否拥有对”selectAccount“修改(modify)的权限。

代码安全检测
有时候需要在代码中直接执行权限的限制而不是使用@Restrict注解,这时候直接调用Identity.checkRestriction()方法对安全表达式进行评估即可,例如:
public void deleteCustomer() {
Identity.instance().checkRestriction("#{s:hasPermission('customer','delete',selectedCustomer)}");
}
如果安全表达式评估结果为假,那么会执行以下任意一种动作:
--如果用户没有登陆则抛出NotLoggedInException异常。
--如果用户已经登陆则抛出AuthorizationException异常。
同理,也可以在代码中直接使用Identity.hasPermission()和Identity.hasRole()方法:
if (!Identity.instance().hasRole("admin"))
throw new AuthorizationException("Must be admin to perform this action");

if (!Identity.instance().hasPermission("customer", "create", null))
throw new AuthorizationException("You may not create new customers");

参考文档

星期一, 三月 12, 2007

JBoss Seam Develop tips

1. 分离测试和业务代码,新建一个源代码目录“test”,修改build.xml:
--在Property声明部分增加“test.java.dir" Property:
《!--src.java.dir was generated by seam gen--》
《property name="src.java.dir" value="src" /》
《!--test.java.dir added by developer manually--》
《property name="test.java.dir" value="test" /》
--修改target ”compile“的”javac“,添加test.java.dir到源代码目录:
《!--javac was generated by seam gen--》
《javac classpathref="build.classpath" destdir="${jar.dir}"
debug="${javac.debug}" deprecation="${javac.deprecation}" nowarn="on"》
《src path="${src.java.dir}" /》
《!--test.java.dir added by developer manually--》
《src path="${test.java.dir}" /》
《/javac》
--修改target “test“,把test.java.dir中的testng测试用例定义文件copy到测试classpath,增加以下语句:
《copy todir="${test.dir}" flatten="true"》
《fileset dir="${test.java.dir}"》
《include name="**/*Test.xml" /》
《/fileset》
《/copy》
--添加target “test_clean",并修改target ”test“,把”test_clean“加入”depends“属性:
《target name="test_clean"》
《delete》
《fileset dir="${test.dir}"》
《include name="**/*Test.xml" /》
《/fileset》
《/delete》
《/target》
《target name="test" depends="test_clean,jar,war,ear" description="Run the tests"》

2.测试驱动开发,Jboss Seam采用TestNG作为测试框架,同时支持Unit Testing(单元测试)和Intergration Testing(集成测试),其中前者主要用于分离地测试各层中特定的逻辑组件,
而后者负责测试除了页面以外的整个应用系统覆盖了各层的功能实现。
--随Jboss Seam 1.1.0.GA分发的Hibernate的JPA实现包hibernate-all.jar无法正常工作,需要更换最新的实现。
--Jboss Seam 1.1.0.GA文档中的”19.1. Unit testing Seam components“ 示例代码无法正常工作,建议参考example中的booking示例的BookingUnitTest.java,单元测试类直接继承于SeamTest。
--为了便于测试,简化测试代码的复杂度和提高测试执行效率,把有关EnityManager的管理代码抽取到一个共同的测试基类中,并且使用TestNG框架的方法级别和类级别的前置和后置代码功能,为每个测试类的每个线程保持一个EntityManager,每个方法绑定到一个Transaction,在执行方法的测试代码前自动打开事务,在方法执行完毕之后回滚事务,通过这种方法可以隔离各个测试方法不受外界影响也避免了频繁创建EntityManager带来的系统消耗。代码如下:
package com.psims.test;

import javax.ejb.CreateException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.jboss.seam.mock.SeamTest;
import org.testng.annotations.Configuration;

import com.psims.base.BaseConstants;

public class BaseTest extends SeamTest {
private static EntityManagerFactory emf;

private ThreadLocal entityManagerLocal = new ThreadLocal();

public EntityManager getEntityManager() {
EntityManager em = this.entityManagerLocal.get();
if (em == null || !em.isOpen()) {
em = getEntityManagerFactory().createEntityManager();
this.entityManagerLocal.set(em);
}
return em;
}

public EntityManagerFactory getEntityManagerFactory() {
if (emf == null || !emf.isOpen()) {
emf = Persistence
.createEntityManagerFactory(BaseConstants.PERSISTENT_UNIT);
}
return emf;
}

@Configuration(beforeTestMethod = true)
public void beginTransaction() {

EntityManager em = getEntityManager();
em.getTransaction().begin();
}

@Configuration(afterTestMethod = true)
public void closeTransaction() {
EntityTransaction et = getEntityManager().getTransaction();
if (et != null && et.isActive()) {
et.rollback();
}
}

@Configuration(beforeTestClass = true)
public void createEntityManager() {
this.getEntityManager();
}

@Configuration(afterTestClass = true)
public void closeEntityManager() {
EntityManager em = getEntityManager();
EntityTransaction et = em.getTransaction();
if (et != null && et.isActive()) {
et.rollback();
}
em.close();
this.entityManagerLocal.remove();
if (emf != null && emf.isOpen()) {
emf.close();
}
}
}
3.在ManyToMany映射时,如果是双向关联需要在被控方设置”mappedBy“属性。和inverse雷同。
4.难道Session Context范围的Component可以自动初始化,在使用@In注入的时候,不需要(create = true)?
5.把Entity Bean直接使用@Name声明为Seam Component使用时,如果在使用集群的时候,效率会有问题,尽量
把Entity Bean作为Session Bean的一个属性来使用。
6.使用Jsf组件调用后台服务的时候,可以传递参数
action="#{hotelBooking.selectHotel(hot)}"
可以实现选择DataTable中的一行,这样就可以避免在后台服务组件中声明@DataModelSelection属性。
7.可以在不提交任何jsf Form的情况下调用Action并传递request parameter,而且他没有使用
任何的javascript,可以通过右键,“在新窗口中打开”的方式执行。
8.由于默认一个Conversation的生存范围仅仅持续一个Request,若需要跨多个Request,必须使用@Begin
和 @End 来限定。
9.在实现service层时,把实现查询功能的seesionbean的生存范围设置为Session而不是Conversation,
可以避免频繁的创建和销毁Component实例。
10.区分哪些状态信息适合于生存在哪个上下文中是合理正确使用Seam框架的基础。
11.EnityQuery 对象实现了对Enity的分页查询功能,继承者直接Override public String getEjbql() 方法,
并返回实际的ql语句即可,在使用Ejb继承EnityQuery时,还需要Override public setEntityManager(EntityManager em)方法,
以@PersistenceContext形式注入EntityManager。
12.Query是EntityQuery的抽象基类,它在内部封装了大部分通用的查询逻辑,其中getEjbql()方法负责返回ql查询语句的模板,如:
select e from Person e where lower(e.lastName) like lower( #{examplePerson.lastName} + '%' ) and
e.age = #{examplePerson.age} and e.gender = #{examplePerson.gender}
而parseEjbql()方法负责解析ql语句的格式,把需要设置的表达式查询参数和约束参数分解出来,其中queryParameters中
保存了形如:
#{examplePerson.age}
#{examplePerson.gender}
的表达式EL查询参数名称,
parsedEjbql保存使用符号参数替换EL查询参数后的ql语句了形如
select e from Person e where lower(e.lastName) like lower( :p1 + '%' ) and e.age = :p2 and e.gender = :p3
parsedRestrictions保存了约束语句,restrictionParameters保存了约束参数。
13.在实体Bean中不要直接使用HashCodeBuilder.reflectionHashCode and EqualsBuilder.reflectionEquals,
它们会引发[LazyInitializationException]异常,估计是由于动态代理的原因。
14.场景:Service由SFSB实现,DAO由SLSB实现,Service使用@In注入DAO实现,DAO使用@PersistenceContext由注入EntityManager.
现象:在页面上执行CUD操作时,无法完成操作,页面和后台均无无错误信息,或者提示session is null or closed
原因:使用@PersistenceContext注入的EntityManager的事务为标准类型,即边界为最外层SB的方法,而Seam中的Transaction
需要使用type=Extended类型的EntityManager
方案:使用@PersistenceContext(type = EXTENDED),需要使用SFSB 或使用@In(create = true) 注入在components.xml中定义好的 core:managed-persistence-context.
15.Seam Managed Transactions
Transaction management for extended persistence contexts. A transaction spans the restore view, apply request values, process validations,update model values and invoke application phases. It is committed when invoke application is complete, or renderResponse() or responseComplete() is called. A second transaction spans the render response phase.
场景:SB拥有声明性事务管理,默认容器会自动在SB中的个方法开始调用的时候开启新的事务,在方法结束的时候提交事务.
(或者如果是SB调用SB,延用已存在的事务)
现象:在使用ORM的lazy fecthing的时候会抛出LazyInitializationExceptions异常.
原因:当在View中访问惰性加载的属性时,已经超出了Transaction的边界,所以需要使用open session in view模式来将整个
request生命周期纳入Transaction中,在View 执行Render操作之后commit,这个会有一个问题,当事务失败的时候,view已经
被渲染完毕,使view表现了与persistence不一致的状态.
方案:首先使用Extended persistence context,并将scope拓展为conversation,而不是request.
其次采用为每个request启用两阶段Transaction,第一阶段始于JSF的"restore view" Phase,终于"invoke application" Phase,第二个阶段覆盖"render response" Phase.
16.扩展的持久上下文extended persistence context, The entity retrieved in the query remain in the managed state as long as the bean exists, so any subsequent method calls to the stateful bean can update them without needing to make any explicit call to the EntityManager.
17.测试的时候使用setField(hb, "facesMessages", new FacesMessages());
setField(hb, "log", new LogImpl(HotelBookingAction.class));
setField(hb, "events", new Events() { @Override public void raiseEvent(String type, Object... params) { assert "bookingConfirmed".equals(type); } } );

(译)在Rails的地盘耍横(基于Seam Eclipse Tools的5分钟快速开发演示)

原文:Beating Rails in its own game (5-minute movie on Seam Eclipse Tools)
By Michael Yuan

你能在5分钟写出一个完整的包含8个关联表格的CRUD Web应用吗?并且需要支持以下功能:
× 1对1,1对多,多对多关联(能够完成遍历和查询功能)
× 联合主键
× 查询任意列
× 分页查询
× 根据数据库定义自动获取必要的条件字段
× 基于AJAX的输入校验
× 提供完整的日期控件
× 具备即时可用的访问权限控制架构(仅仅需要提供java登陆验证代码即可工作)
× 完全使用基于CSS 和XHTML技术的页面布局

那么,你能使用java来完成这些吗?
使用最新发布的Red Hat Developer Studio开发环境和JBoss Seam框架,你可以仅仅点击几下鼠标就能完成上面所有的要求。
这儿有一个5分钟的flash来演示如何去做:
Seam开发演示

对于喜欢使用命令行工具而不习惯Elipse里的窗口工具的开发者来说可以使用具有相同功能的Ant脚本,具体请参考Seam Gen文档
这个演示仅仅是Ram Venkataraman, James Williams, Max Rydahl Andersen, and Max Katz 一起为 EclipseCon 2007准备的4小时的教程中的一小部分。完整的教程涉及了JBoss Eclipse tools for server management, Seam Gen, database browsing, database query analyzer, Facelets visual editing, business process editor, rules editor等等很多内容。等我们EclipseCon 2007归来之后,将来可能会把整个教程都发布到JBoss网站上,敬请期待。

星期三, 一月 31, 2007

开源共思

“开源”,出自自由软件社区,意指软件开发人员或软件公司在发布其软件产品的同时公开其产品的源代码,以帮助产品用户更好地理解和使用软件。根据不同的授权协议(GPL、LGPL、APL...),用户拥有不同的使用权限,比如修改、引用、甚至商业化等等。最著名的开软件莫过于Linux、Apache、Postgresql,在它们的带动下开源社区人丁兴旺,高手辈出,新软件好软件层出不穷。现在可以毫不夸张的说,无论个人用户还是企业用户,都能在开源世界找到适合自己的解决方案,当然有时候开源软件的易用性不如微软或苹果的软件出色,但在功能上决不逊色于任何专有软件,所以适当的培养自己的动手能力会有助于你更好地享用开源大餐。那么我们能从轰轰烈烈的开源运动得到些什么启发吗?我个人认为是肯定的。每一个优秀的开源项目背后都会有一个出色的社区,就是通过这个社区分布于世界各地的程序员才得以交流协作,打造出优秀的开源软件。开源社区并不是一个简简单单的自发组织的、虚拟的网络社区,它根植于]理乍得·马修·斯托曼 (Richard Matthew Stallman, RMS,生于1953年)式的黑客文化和信奉民主、自由的社区精神。在这种类共产主义信仰的驱动下,每一个社区成员都处于积极奋进的状态,相互之间能够紧密协作,创造力源源不断地注入社区,反过来激励更多的成员投入到创作之中。我想,我们最需要关注的就应该是整个开源社区的背后蕴藏着的那些东西。现在但凡有个把人的公司都会大谈团队精神是如何如何的重要,但能真正形成一个良好的、自组织模式的团队的公司还不多。那么为什么开源社区能比公司团队以一种更有效的方式组织在一起,我想,主要是因为“开源”这个神奇的词汇,开源社区的成员都是“开源”的拥护者,而且不仅仅是软件开源,更重要的是他们之间的思想也是开源的,相互之间能够真正的坦诚相待。而公司团队由于个人之间存在的利益冲突,往往不能做到就事论事,进而影响了团队的凝聚力。简单的就是美的,有时候思想简单一些可以促进我们自己成长和周围环境的和谐。如果我们的思想也能够开源的话,那么你我之间就更近了一层。借用一下“开源”的意念,让我们共同倡导“共思”(Open Thinking)。 

星期四, 一月 25, 2007

Behavioral differences


Method
Parameter format
Lookup failure behavior
Usage example


ClassLoader.
getResourceAsStream()
"/"-separated names; no leading "/" (all names are absolute)
Silent (returns null)

this.getClass().getClassLoader()
.getResourceAsStream
("some/pkg/resource.properties")


Class.
getResourceAsStream()
"/"-separated names; leading "/" indicates absolute names; all other names are relative to the class's package
Silent (returns null)

this.getClass()
.getResourceAsStream
("resource.properties")


ResourceBundle.
getBundle()
"."-separated names; all names are absolute; .properties suffix is implied

Throws unchecked
java.util.MissingResourceException
ResourceBundle.getBundle
("some.pkg.resource")

星期四, 一月 11, 2007

Compiere 实施步骤

1.产品漫游—以熟悉 Compiere 应用程序

2.实施方法 —参考

3.测试—可参照Compiere 的示例实体"Garden World"

准备

您可能需要准备账户、业务伙伴和产品的导入。尽管您可以在之后进行所有记录的导
入,但若设置账户导入则会节约您的时间。在初始化阶段,提供对 CSV(逗号分隔
值)导入的支持,其中 CSV 文件含有预定义的属性列表。这是 导入 工具完整版的子
集,您可以在稍后使用。

账户&CoA(会计科目)

关于会计科目设置的详细资料请参考 这里 。

初始化实施

您需要以系统管理员身份以进行初始化实体的设置。

此程序将创建用户、角色,及单据类型、业务伙伴、产品等的"标准"实体。在运行
后,您可以创建及打印第一张发票。

设置程序将创建两个用户: "实体级别"角色的用户,具有维护规则和进行事务处理的
权限。 "组织级别"角色的用户,具有进行事务处理的权限。

精化实施
完成初始化实施后,您已经可以开始 Compiere 的运行了。但是你可以去"初始化实体
设置"工作流程以检查、更新。

Compiere 实施方法

Compiere 被设计为支持快速上线。主要优势在于 Compiere 独特的技术特性 - "上线
后的结构更改"(请参考" 信息结构 "),让您能在上线以后进行任何更改。这使得没
有必要存在非常细致的分析和配置阶段,因为" 如果您忘记了某些东西或设置错误了
什么"那么重新实施不是一个好做法。在许多 ERP 项目实施过程中发现必须进行某个
主要变更,又或者发现了某些遗漏,结果导致上线之前不得不重新实施,造成资金、
人力、设备和时间的浪费。

因此,这里为快速和方便实施提供了一些指引。其中的大多数,实际上不仅应用于
Compiere 这一 ERP 的实施 - Compiere 不过使它更容易罢了。

技巧 1 :尽量使用固定期限的实施合同,并坚持它。这可获得预定义交付(实施服
务)的公开价格。

成功案例(Use Cases)

用例(Use Case)是一个业务过程,比如订单输入、收款、发货等。基本而言,它是
您在业务开展中所做事情的清单。创建3种类别:

(1)紧迫 - 运营您的业务所必需的基本业务流程。

(2)便利 - 使业务流程更快、更容易、更有效。

(3)支持 - 帮助做出正确的决策、报表、分析...

有意思的是,在许多实施中,优先级似乎恰好被弄反了,这很令人吃惊。优先级(3)
提供了更高的信息级别,所以常常是战略决策的催化剂,因而它们是重要的,但优先
级(1)确保了您能够得以制定战略决策。软件供应商的售前活动通常完全聚焦于优先
级(3)上,并且咨询公司也因此而繁荣 - 不过,请考虑优先级(3)中有多少是必须
等到上线以后方能做出决策的。

这样说来,原型阶段应持续多长时间呢?这依赖于您的风险级别,至少优先级(1)的
所有用例应当准确工作。在此基础上,您的感觉更好,主意自然妙,轻松确定下一步
将完成的优先级(2)和(3)用例。

优先级(1)的用例工作正常时,您肯定无法进入负面的媒体报道标题了。

原型(Prototype)

每个产品都有它自己的方式去完成目标。如果您强制让 SAP 的行为像 Oracle
Applications 那样,或者像您现存的实施那样 - 那么无疑就增大了失败的风
险。Oracle、SAP、PeopleSoft 等商业应用系统实施的公开失败案例中,全都归入此
类。通常,失败与产品无关,而是实施者及客户所持的不现实期待和呆板态度所导
致。

因此,您如果要获得成功则需要一个操练场,以了解实现目标的最佳方式以及备选方
式。如果您暂行规定此阶段,那么您的上线系统其实变成了您的原型。Compiere 不会
介意这一点,并将精确地工作,然而您不过在系统中放入了一些测试数据而已。

技巧 2 :所有的上线系统都包含一些"杂音"数据,因此不必尝试拥有一个100%干净的
系统。如果在 Compiere 中无法删除这些"杂音"数据,那么可以隐藏它们(以满足一
致性的要求)。

尽早引入全部用户

变更有时不会受到热烈的欢迎。许多项目集中于"超级用户"或"用户代表团",限制了
给正常运营带来的打扰。适度则没问题,但请尽早引用所有的用户。

原型阶段的结束通常是进行总体导入的好时机。此时人们可尽情使用或肆虐系统,而
不会产生什么负面后果。您也可趁机获得非直接的确认,即覆盖了优先级(1)中的全
部问题。

因此,请将您以及超级用户们的 Compiere 解决方案展示出来,甚至开一个 Party,
让所有人都看看并试用您的杰作 - Compiere 系统原型。

迭代式开发

请习惯于循环:

设置较短时间内可完成的、较小的目标
让它工作
为下一次迭代总结经验
" 大爆炸 "方式 - 一切都同时开始工作 - 则使目标难以达到。

某些方面您可能第一次不能正确处理,所以小步骤产生的成功经过不断累积(即使遇
到"事故"也可快速恢复),就可完成最终目标。

上线以后

既然业务运营已处于上线状态中,您就有了时间和知识可以开始调查,Compiere 在业
务的策略方面能够怎样帮您。这使您得以更好地利用 Compiere,因为您已经对系统有
了更多的理解。

技巧 3 :为两个项目做出预算,一个是上线实施项目,另一个是上线6个月以后的项
目,用以完全发挥 Compiere 的功能。

对于6个月后的项目,如果不考虑计划的详细程度,需要决定的是:早实施还是晚实
施。用户不会再有变得惊慌的理由,"会议室驾驶仓"(或"Compiere 见面会")可以为
他们提供良好的培训基础。

Compiere 最大的优势这时就表现出来了:

已改变的优先级,新的业务和市场开发,或者新的视角要求改变 Compiere 的设置。
不久之后,您的用户将变得适应,并将更进一步地控制系统。

Compiere 允许从绝大多数情形下轻松恢复,因为它被设计为" 自恢复 "。

一切听起来不错。当然,使用软件支持服务,可以将问题的后果最小化。

切换上线

需要决定一个问题:是否并行运行。众所周知,并行运行意味着双倍的工作。因此,
在您的"Compiere 见面会"中,要与您的用户商量,看看他们是否对系统切换感到适
应。

技巧 4 :"用户认为无需并行运行"是一个重要指标,如不考虑(项目经理做出)是否
并行的决定。

真实系统

不要等到"一切"问题都解决。那样可能永远也解决不完。因此,在您删除了原型(的
确如此!)以后,开始使用新的实施和真实数据。

在这个阶段中(记住,您挑选出了所有的紧迫问题),主要的挑战是从已有系统将数
据迁移至Compiere中,并做必要的定制工作。

一个重要部分是小型但正式的"会议室驾驶仓"(您可在此模拟驾驶仓尝试 Compiere
飞车,无需系安全带)。在备份以后,您给予用户了解和尝试系统的机会。不要只计
划一次"会议室驾驶仓",完全可计划三次或更多,这依赖于实施的复杂性。这些
"Compiere 见面会"不应过长,用来帮助传播消息和减轻转换带来的心理压力 。

"会议室驾驶仓"也是对您的备份与恢复过程的检验。

获取经验的另一途径是升级和打安装补丁。Compiere 使得它们很容易,通过这些设置
可以获得经验。

背景

上面推荐的实施方法正变得越来越流行。基于 快速原型法 的方法论已经出现了较长
时间。 XP (极度编程 )是快速 、安全交付新技术的方法论(软件开发流程)。只
需用实施任务替代编码的部分,它就非常适用于应用软件实施项目。要了解关于 XP
的更多信息,请检查 Google 。

Rational 的重量级流程 Rational Unified Process(RUP)近来已从强烈反对 XP 转
为拥抱它。现在,Rational 为 RUP 提供一个 XP 插件。

Compiere 的会计科目

Compiere 需要用到一套账户用于系统操作,即便其中某些可能永远不会用于过账
(例:如果您没有外币事务处理,则像已实现盈利这样的账户将不会被用到 )。当创
建实体时,Compiere 需要创建一套默认的账户(会计科目) 。

AccountingXX.xls / AccountingXX.csv
文件 AccountingCN.xls、AccountingHK.xls 和 AccountingTW.xls分别对应于中国大
陆、香港和台湾的基本会计科目(包含于 QuickIT 实施工具包 的会计科目模板中
)。

文件 AccountingXX.xls 是导入和维护您的会计科目表的基础。

文件名中的 XX 代表国家或地区代码 - 因此文件 AccountingUS.xls 是美国风格会计
科目的良好基础。

您初始化新的实体(初始化实体设置)时,文件结构要求保持不变。在此阶段,仅必
填科目被导入/创建(在 Account_Default 中包含了值 - 第 H 列)。

在初始化设置以后,您使用它导入您的科目层次,或用于报表。为此,您可更改导入
格式以满足您的需求。

请注意,文件名只是一个建议。会计科目的早期结构对应于文件
NaturalAccount.xls/csv。文件 AccountingXX.xls/csv 的结构是一个超集。

如果您修改了文件,则 必须导出 .xls 文件为 .csv (逗号分隔值)格式,因为
Compiere 只能读取 .csv 文件。导出的结果文件应当位于 %COMPIERE_HOME% 的
"data/import"子目录下。

术语

会计科目 (CoA) = 自然账户的列表 - 它随 Accounting*.xls/csv 文件提供
账户 、 组合 或 有效组合 = 会计分段组合的值;分段在会计模式中定义
如:01-1600-HQ-应付账户(此处是公司和自然账户)
自然账户 = 账户分段 - 在您账户结构中的元素;这是您在 AccountingXX 文件中导
入的内容
如:1600 - 应付账户
细节 - 创建您自己的会计科目

您需要有不同的账户对应于每个默认账户。例如,即使您不想或不需要区分货币盈余
和货币亏损,Compiere 仍然需要这两个账户。您可合并科目,比如通过总账日记账分
录。
Compiere 需要最小集合的账户。这些账户由"Default Account"列的内部列名标识 -
例:B_ASSET_ACCT
您可更改、添加或删除某些行,只要存在一行对应于每个默认账户即可。
如果您不喜欢提供的示例会计科目(CoA),可采取如下步骤 :

更改行(值/关键字、名称、描述),以符合您的会计科目
删除所有的行,但含有默认账户的那些行除外
在您的会计科目中添加其它账户

各列的解释,可参考 Accounting*.xls 文件中的注释。注意,列名仅作为说明之用,
可以修改。

A - 账户_值

自然账户必须填写的主键(完全用户自定义),可以是数字或字母-数字,长度不超过
20个字符。请注意,每行必须唯一。

B - 账户_名称

自然账户必须填写的名称(完全用户自定义),长度不超过60个字符。

C - 账户_描述

自然账户可选的描述(完全用户自定义),长度不超过255个字符。

D - 账户_类型

必须填写的账户类型(如资产、负债、所有者权益、费用、资产、备注)。请注意,
首字母必须是 A、L、O、E、R 或 M。例如:"L - 负债"代表中文的负债账户类型。

E - 账户_符号

可选的账户符号标识(当前未实现,计划用于财务报表)。可选项包括自然(默
认)、借项和贷项。请注意,首字母必须是 N、D、C 或为空。例如:"D - 借项"代表
中文的借项账户符号标识。

F - 账户_单据控制

可选的账户单据标识(换言之,该账户仅能通过分类账过账,无人工日记账分录。为
简化科目对账,推荐这样做)。请注意,首字母必须是 Y、N 或为空。例如:"Y - 是
"代表中文的"是"账户单据标识。

G - 账户_汇总

必须填写的汇总账户标识(换言之,您不能过账到汇总账户,它们仅用于报表)。请
注意,首字母必须是 Y、N 或为空。例如:"Y - 是"代表中文的"是"汇总账户标识。

H - 账户_默认

可选的默认账户分配,这是账户的默认分配列名称。这是实际的列名称,请勿修改其
内容。您需要让所有默认账户至少存在单独的一行与之对应,且需要让所有的默认账
户被列出。

例如:B_INTRANSIT_ACCT 表示该账户是默认的银行在途账户。您可能不会用到它,或
希望为每家银行使用不同的在途账户,但是您仍然需要包含此行。

I - 账户_父

可选的父账户账(列 A )。它需要精确匹配。用于在您导入会计科目表时建立账户层
次。请注意,该列在初始化实体设置的过程中会被忽略。

J/K - 资产负债表_值,资产负债表_名称

可选的资产负债表行值/主键与名称。用于创建财务报表行集合。导入格式已经预定
义。

L/M - 美国1120资产负债表_值,美国1120资产负债表_名称

可选的资产负债表行值/主键与名称。用于创建财务报表行集合。导入格式已经预定
义。在这里,它以美国税代码的 Form 1120 为基础,不同于标准的美国资产负债表结
构。

N/O - 损益表_值,损益表_名称

可选的损益表行值/主键与名称。用于创建财务报表行集合。导入格式已经预定义。

P/Q - 美国1120损益表_值,美国1120损益表_名称

可选的损益表行值/主键与名称。用于创建财务报表行集合。导入格式已经预定义。在
这里,它以美国税代码的 Form 1120 为基础,不同于标准的美国损益表结构。

R/S - 现金流_值,现金流_名称

可选的现金流有行值/主键与名称。用于创建财务报表行集合。导入格式已经预定义。

compiere resource list

<div class="layout">
<div class="layoutregion">
<div id="g_body"><p>[请大家一起编辑本页面] </p><p> </p><p>资源搜索工
具:</p><ul><li>Google:<a href="http://my.donews.com/pastoral/">比特酋长
</a>为Compiere定制的Google custom
serach engine:<a
href="http://www.google.com/coop/cse?cx=015651053727539904439%3Ad58dvnv279e">Compiere
CSE</a>。你可以把它添加到你的Google PersonalHomepage,你也可以为其添加站
点;</li><li>eMule:也许应该上去搜索一下;</li></ul>
<p> </p>
<hr><h2><font size="4"><b>
Compiere相关项目网站</b></font>:<br>
</h2><dl><dl><dt><a
href="http://compilo.sourceforge.net/index.html">Compilo
- Compiere developer documentation.</a> </dt><dt><a
href="http://sourceforge.net/project/showfiles.php?group_id=111366">SF.net:
CompiereUtil</a>     <a
href="http://www.compierefans.org/blog/index.php">Compiere Util Project
HomePage</a> </dt><dt><a
href="http://sourceforge.net/projects/comxe">SF.net: Compiere on Oracle
XE</a> </dt><dt><a
href="http://sourceforge.net/projects/compiere-portal">SF.net: Compiere
Portal</a> </dt><dt><a
href="http://sourceforge.net/projects/cmpcs/">SourceForge.net:
Kompiere Libero (Manufacturing)</a> </dt><dt><a
href="http://www.compierefans.org/blog/index.php"><br></a> </dt><dt><a
href="http://compiere-mfgscm.sourceforge.net/">Compiere MFG &amp; SCM</a>
</dt></dl></dl>
<blockquote dir="ltr" style="margin-right:0px">
<p><a
href="http://www.openbravo.com/index.php?option=com_content&task=view&amp;id=130&Itemid=244">openbravo
ERP&amp;CRM</a>   
<a href="http://www.adempiere.com/">ADempiere</a></p></blockquote>
<h2>博客与论坛</h2>
<dl><dl><dt><a href="http://bbs.kuke.info/forumdisplay.php?f=18">上海酷克
Compiere论坛</a> </dt><dt><a
href="http://petershen.bokee.com/index.html">pshen的博客</a> </dt><dt><a
href="http://www.oslabs.org/">OSLabs - Home</a> </dt><dt><a
href="http://www.ohloh.net/opensource/software/compiere">Compiere ERP
+ CRM Business Solution
- Ohloh Metrics Report</a> </dt><dt><a href="http://red1.org/">red1 open
source empire</a>
</dt><dt><a
href="http://www.compiere.org/documentation/dbLogical/index.htm">Compiere
AD ER-Studio Intranet Documentation</a> </dt><dt><a
href="http://www.compiere.org/technology/build.html">Compiere Technology -
Building Compiere from Source</a>
</dt><dt><a href="http://www.compierefans.org/">Compiere Fans-zh</a>
</dt><dt><a href="http://www.smileblog.com/">Compiere Blog-zh</a>
</dt><dt><a href="http://groups.google.com/group/Compiere-China">Google
Groups Compiere-China</a> </dt><dt><a
href="http://www.workrun.com/21/0.htm">Compiere
ERP&amp;CRM</a> </dt><dt><a
href="http://www.knowledgesuccess.com/compiere/">knowledgesuccess</a>
</dt></dl></dl>
<h2><font size="4"><b>咨询与服务公司</b></font><br></h2>
<blockquote dir="ltr" style="margin-right:0px">
<dl><dt><a
href="http://entpiere.interpack.org/portal/entpiere/index.htm">首页 - 恩普
派</a>
</dt><dt><a href="http://www.astidian.co.za/comp.htm">Astidian Systems</a>
</dt><dt><a href="http://www.e-evolution.com/kompiere/">e-Evolution</a>
</dt><dt><a href="http://www.mycompiere.com/support/">myCompiere.com
Support</a> <br>Compiere-China     [  <a
href="http://www.compiere-china.com/support/setup_server.htm">Compiere-China
安装</a>   <a
href="http://www.compiere-china.com/download/dl_software.htm">Compiere
Download</a>  ]<br><a href="http://www.eousoft.com/">益用软件</a>
</dt></dl><dt><a
href="http://www.zoapcon.com/www2/Web/product/technique/systemstruct.htm">ZOAP
源科顾问有限公司</a> </dt>
<dt><a href="http://www.huahu.com.cn/">RMS ERP&amp;CRM 企业解决方案 DNN BPM
Suite 工作业务流程规划 门店管理</a> </dt>
<dt><a href="http://www.desoo.com/">Desoo 戴速: Compiere ERP &amp; CRM 企业
解决方案</a> </dt>
<dt><a href="http://www.adaxa.com.au/">ADAXA</a>       [<a
href="http://www.adaxa.com.au/index.php?option=com_content&task=section&amp;id=3&Itemid=27">Compiere
&quot;How-To"</a><a
href="http://www.adaxa.com.au/index.php?option=com_remository&amp;Itemid=53&func=selectcat&amp;cat=1">]  </a>
</dt>
<dt><a href="http://www.zhichi.cn/sa8.htm">compiere系统优势|北京智驰科技有
限公司</a> </dt>
<dt><a href="http://www.yugasoft.com/compiere.htm">上海优格软件有限公司
</a> </dt>
<dt><a href="http://www.janus-software.com/compiere_dl.html">Janus
Software</a> </dt></blockquote><wbr></div>

星期二, 一月 09, 2007

Compiere 安装在SUSE10下的成功实例

开源的ERP当然要用开源的操作系统啦,要不然,就本末倒置了。本文介绍了一个在
SUSE10下成功部署Compiere的实例,可作为参考。


安装前的准备
操作系统:Open SUSE Linux 10.0(内核2.6.9)
JAVA:SUSE10.0默认安装的是JRE1.4.2,不过Compiere网站上要求的是1.5.0,所以也
下载了一个SUN JDK1.5.0
Oracle:XE 10.0.2(后来证明XE完全可以使用)
Compiere:最新253b压缩包
别的没太多好说的,只有Oracle的XE版本,后来证明完全可用,并且安装相对简单
(只有一个rpm包),而且尺寸也小(所有的东西装完以后,我的SUSE分区只剩下
170M了
如果你准备用XE,从SUSE裸系统开始装这一大套东西只需要2G就可以了,但是如果用
标准版甚至企业版,那么准备4G空间吧!

安装过程
其实很简单,完全按照www.compiere.com上面的安装向导来就行了,注意一定要认真
仔细的一步一步操作
我试验了一下用SUSE自带的JRE1.4.2来跑RUN_setup.sh,结果不出所料报告了java方
法错误,看来必须用1.5.0
新建了一个用户comp,并且在~/.bashrc强制了PATH和相关的JAVA环境变量指向1.5.0
新建用户是个好习惯,一来在这个状况下可以单独为其设定1.5.0版本的JAVA为缺省
值,不会影响到其他用户继续使用1.4.2,二来,为一个服务建立一个特定的用户也符
合UNIX的安全习惯。
别忘了给comp加入到dba组中,并且在bashrc里面加上引用Oracle环境初始化脚本的
行。具体的做法在安装Oracle XE的rpm包后的设置过程中都有提示。
用root把compiere包解开到/opt,并且更换所有者为comp,给sh脚本赋予可执行权限
重新用comp用户登录桌面,语言一定要选择英语(后面会告诉你为什么),打开一个
终端检查JAVA环境变量和虚拟机版本,检查Oracle连通性(按照compiere主页的安装
步骤来)
一切就绪以后,就可以执行安装脚本RUN_setup.sh了,其实这个脚本是一个配置工
具,执行它会出现一个窗口,里面要求填入一些值,Test通过以后就可以保存并进行
下一步操作了。这里只要注意3点:A数据库名字叫做"XE"(如果你用XE版本的
话);B对于我的comp用户来说,不能使用<1024的端口,因此你要把缺省的端口改一
下,比如10080/10443等(注意Oracle默认占用8080端口,不要冲突了);C数据库用
户compiere不需要你手工建,安装程序会自己建的!
SAVE了以后就可以继续安装过程了,一般来说就不会再出什么问题了。别忘了设好
COMPIERE_HOME变量
最后都弄好以后,运行RUN_Env.sh不报错就算成功了
最后启动服务RUN_Server2.sh,实际上就是启动了内建的JBoss
最后打开浏览器就可以使用客户端了。根据我的经验,除了comp以外其他的没有设置
JAVA1.5.0为缺省jvm的用户一样可以使用WebStart客户端,因为在SUN JDK1.5.0安装
的时候自动把所有的WebStart连接绑定到了1.5版本的javaws上去了,因此无论谁在浏
览器中点击了WebStart的连接,默认启动的都是1.5的javaws
心得体会
一定要注意java的版本
1.5的java在SUSE10上面中文字体有问题,所以我强调第一次要用英文环境运行安装程
序,不然出来的中文字体都是方块。解决这个问题花了我一些时间,主要是1.5版本的
字体配置文件是按照特定顺序读取的,首先读取跟当前操作系统名称和版本对应的那
个文件,然后读取相似性越来越小的配置文件。一开始我没搞清楚这个顺序走了弯
路。
解决方法就是,把原来1.4.2的字体配置文件copy过来,并且命名为
fontconfig.SUSE.properties 这样优先级就是最高的了。如果设置好了java字体,那
么就可以用中文环境运行安装程序和客户端了
安装界面中还有DB2,sqlserver等数据库,IBM的虚拟机,以及其他类型的aplication
server可选,不过有些带<>箭头,估计还是测试阶段,过两天我会试一下win2K+IBM
JDK1.5+DB2的组合
登录界面有中文选项,但是进去以后还是英文界面,原来中文包是要收费的,靠
web界面的应用基本上没怎么做好,看来这方面要等很久了
Oracle XE版本挺好用的,作为试验和学习足够了,就是数据库名"XE"我迷惑了很久才
知道了,看了Oracle网站上的文档才知道的。

Compiere 贸易行业ERP的首选

周从所知,compiere目前在生产这块,也不是很成熟,但相当开放,可以满足几乎所
有生产企业的二次开发需要。

优化的贸易优势Compiere让您对货物在销售、采购、盘点、定价等方面的管理得
心应手。优化的客户关系,有利于增加新客户、保留老客户,最大化每个客户的生命
周期价值。优化的供应商关系,让您占据更有利的议价地位。

  标准化的Compiere贸易业解决方案,用您所需。
  集成的财务管理
Compiere让财务管理变得轻松。销售、采购、库存等相关的事务处理,自动过
账。您还在使用手工方式填写会计分录、追踪历史账目、定期重复统计
吗?Compiere贸易业解决方案集成的财务管理特性,允许您轻松记账、查账、分析,
简单而统一。
  集成的呼叫中心
Compiere让您的企业能够借助先进的CTI (计算机电话集成)技术,以优良的电话
服务水平赢得更多客户的依赖。业务单据、付款往来、销售机会、服务请求,瞬时识
别与追踪,Compiere贸易业解决方案让您的企业实时响应任何客户的需求。
  集成的电子邮件
Compiere完全满足Internet时代与业务伙伴快速沟通的需求。无论是供应商、客
户,还是企业内部的员工,简单、直接的沟通方式尤为重要。扁平式的管理,需要扁
平式的沟通。Compiere贸易业解决方案让您放心。
  可变更业务流程
Compiere灵活的业务流程允许您的企业快速响应变化的环境。一体化的业务功能
与业务流程,既可单独使用,也可组合使用。即时启用新的业务流程,需要灵活可靠
的一体化企业应用套件,Compiere贸易业解决方案让您能够做到。
  可变更业务功能
Compiere提供安全的用户界面与数据库访问控制。得益于Compiere独特的AD (应
用字典)技术,您不但能对现有的窗口、报表进行字段与布局的更改,而且可以创建包
含任意字段的全新窗口与报表。这一切却无需编写程序或脚本。随需而变,如此简
单!
  按需定制与扩展
Compiere丰富的业务功能仍然无法满足您特殊的业务需求?开放、强大、灵活的
技术架构,加上我们在Compiere项目实施及维护与支持服务方面超过3年的专业经验保
证,Compiere贸易业解决方案随时可以按需定制,按需扩展。
  投资Compiere贸易业解决方案依据企业的业务特征,我们提供贴身的定制、实施
与支持服务。Compiere贸易业解决方案,获取更高利润近在咫尺。

Compiere 的E2IT实施方法赢得6000人企业的赞许

敏捷型ERP项目:打破IT预算常规

如果您需要一个不是很庞大也不是很复杂的 ERP 系统管理公司运作,那么您要应该考
虑"敏捷型"ERP 系统。一位 CIO讲述了轻量级软件是如何为中小企业带来高效益的。
ERP 看起来已经是很古老的概念,它的全称是企业资源计划。如今,新一代的概念如
ERM(企业关系管理)和 SFA(销售自动化)开始受到企业的关注。
没有人再对 ERP 概念产生争议,因为它已经具有相当成熟的定义,并被长期应用于企
业管理当中。新的 ERP 模型正在由庞杂的分析型过渡到快捷的实现型。这种模型对应
了可以被快速高效实施的 ERP 系统。对于敏捷型 ERP 来说,重要的是,它被设计为
效率优先的原则。
敏捷型 ERP 也并非新事物。几年前,康比尔公司的总经理兰迪.纳尔逊在休斯敦进行
一项专业的研究。在做这项研究之前,纳尔逊被聘为 CIO 负责一个 ERP 合同的项目
实施。
"当 ERP 实施为商家带来顾客之时,在1999年我更加迫切地希望从事敏捷实施的研
究。"他解释道。"例如,SAP 推出了敏捷系统被称为 ASAP 或者加速的 SAP。后来发
现大多快速 ERP 产品线都缺乏较多的定制功能。换句话说,快速上线唯一的办法就是
企业需要改变业务流程去适应这套系统。"
敏捷型 ERP 也因此被重新定义,其最大的区别就在于是否预先配置。这种做法可以减
少上百万的开支,并且产生了难以置信的高效率。这为几乎要摇摇欲坠的经济景气状
况带来了翻天覆地的改变。这种敏捷型 ERP 方案为企业节省了在传统 ERP 套装软件
上巨额的投资预算。特别是为了生存而奋斗的中小型公司,能否快捷实施 ERP 对企业
的信息化管理成败至关重要。
敏捷型 ERP 的一个典型代表是支持 E2IT 实施快车道的 Compiere ERP & CRM。这套
完全开放源代码的企业 ERP 系统集成了 CRM 功能,支持敏捷型的实施,能够立即上
线,并在上线后随时根据业务需求的变化而调整。Compiere 的 E2IT 实施快车道包括
评估(Evaluation)、培训(eLearning)、实施(Implementation)、上线
(Transition)这4个顺序相连的步骤。E2IT 实施方法适用于包括 Compiere 系统在
内的所有敏捷型 ERP 系统。
一个敏捷型 ERP 实施的案例
生存问题并非是上线敏捷型 ERP 的原始驱动力。去年英国的马托尔零售店 CIO 詹姆
斯.麦克鲁夫为公司构建了电子库存追踪系统,随之公司新增了120名雇员。没有人向
麦克鲁夫兜售敏捷型 ERP 系统。前任 CIO 达尔夫.爱尔兰在位时,公司有
5,000,000英镑的 IT 预算并增加了4名 IT 专家。但自从麦克鲁夫加入马托尔零售店
以后,情况发生了变化,巨额的IT 预算已经无用武之地,敏捷型 ERP 被作为考虑的
重点。
他很快就体会到敏捷型 ERP 是一种直接、简单且高效的做法。敏捷型 ERP 系统是为
雇员数量少于5000名(收入在2亿美元到5亿美元)的中小企业提供的企业级应用。同
样的功能"财富"500强的企业却花了几年时间才完成。"敏捷型 ERP 是想体验快速增长
的唯一解决方案。"麦克鲁夫说道。
"大多数企业对业务流程并没有规范的定义,或者没有高效的定义。"纳尔逊补充道,"
因此,敏捷型 ERP 的市场目标非常明确。"
敏捷型 ERP 之优点
决定采用敏捷型 ERP 通常是 CIO 们。确定要上线实施通常是需要说服高级主管们
的。
"一旦 CEO 理解敏捷型 ERP 的优势并在实施中的困难阶段给予支持,那么进展就会非
常迅速,毕竟 CEO 确信做了正确的投资。"麦克鲁夫说道。
马托尔零售店的规模决定了麦克鲁夫选择敏捷的 ERP 系统。"为一个拥有6000名雇员
的企业上线敏捷型 ERP 是很具有挑战性的。"麦克鲁夫说道。"首先,这意味着需要替
换掉很多系统,然后需要培训员工如何使用新技术。总而言之,需要做到快速上线
ERP。经过评估,我们确定使用支持快速部署和动态精化实施的 Compiere 解决方
案。Compiere 的免费特性还不是最重要的原因,重要的是 Compiere 支持上线后的任
何调整。"
快速上线 Compiere 已在马托尔获得了成功。整个实施历时3个月。"以 Compiere
ERP & CRM 为基础,我们采用了标准的 E2IT 实施方法,最小化定制工作并且做了充
分的扩展测试。"麦克鲁夫补充道。"这比采用类似的传统 ERP 系统节约了10%的成
本,一些工作被集中到同一个人,公司的业务流程与之前相比具备更高的效率。"
实施的速度也比在线的 ERP 系统要快,在线 ERP 是另一种对中小企业很有吸引力的
解决方案。"整个后台应用采用租赁的方式,直接通过 Citrix 终端技术进行访问。"
纳尔逊说道。"如何减轻雇员和主管们的超量工作压力呢?提供完整的应用将生产、管
理、配送、产品计划等子系统集中到同一数据库当中。"
总之,毫无疑问在线 ERP 的方式对中小企业很有吸引力。就像位于波士顿的 IT 研究
与顾问公司 Aberdeen 组织的副董事长大卫?埃斯库罗所讲,"这种方案可以避免建立
硬件和网络等基础设施的投入。"
接下来,就像 Alschuler 一样,需要放弃已有系统的部分控制流程。这也正如纳尔逊
所说:消除"无价值的冗余工作",这对企业是有益的。"敏捷型 ERP 取代了人工对需
求的检测和对成本、开支的监控,"纳尔逊说道。"许多雇员被更换了岗位并重新安排
到新的工作当中,少数人会不幸地被解雇。"
成功实施的因素:敏捷型 ERP 并非适合所有的企业
"最适合会发生快速变动的动态产业。"纳尔逊说。"上榜名单最多的是技术产业,其次
是零售、服务行业、电信以及近期的能源和电子工业(由于其正在发生的变动和不稳
定的管理环境)。"
纳尔逊认为运输、铁路和化工业也比较适合敏捷型 ERP。
最后一个备受关注的问题,就是如何选择最好的敏捷型 ERP 供应商。必须注意的是,
敏捷型 ERP 最好支持 E2IT 实施方法。
麦克鲁夫建议评估多个敏捷型 ERP 供应商。"如果你想有好的交易,就应当多评估。
可能有更廉价的供应商,同样提供一些高效且高质量的服务。"他说道。"不要略过评
测阶段。花时间确定有没有问题并且雇员是否能够适应这种技术是非常值得的。"
埃斯库勒推荐寻找具有相关行业经验的专业系统集成商。
麦克鲁夫庆幸自己当时选择了开放的敏捷型 ERP 系统 Compiere。就像任何主流技
术,谨慎的计划都是必不可少的。麦克鲁夫提醒 CIO一定要细致地做好方方面面的工
作,敏捷型 ERP 定会不负众望。

Compiere 安装在Debian下Oracle安装及配置

1 安装准备
1.1 系统的准备
本文是在Debian linux下Oracle10g的安装笔记。我假设您已经成功的安装并配置了
Debian Linux。
1.2 依赖包的安装
在开始Oracle的安装之前,请您确保您至少已经安装了以下软件包。
make gcc g++ libc6-dev
注意:我不确 定,您是否只需要安装以上软件包,但我可以确定的是,您必须安装
以上软件包。^_^。软件包的安装: apt-get install make gcc g++ libc6-dev
1.3 创建用户和组
oracle安装需要两个unix用户组和一个运行时的oracle用户。
以root登录:
[root@james]# groupadd dba
[root@james]# groupadd oinstall
[root@james]# useradd -g oinstall -G dba -m oracle
[root@james]# passwd oracle
1.4 创建目录
有很多文档,建议您将oracle安装到一个独立的分区上面。比如:/opt。请您根据
您的需要选择合适自己的安装目录。在本文档中,我们假设 oracle的安装目录为
/usr/local/ora10。
确保有至少3.5G的可用空间。
[root@james]# mkdir -p /usr/local/ora10/product/10.1.0
[root@james]# mkdir /var/opt/oracle
[root@james]# chown oracle.dba /var/opt/oracle
[root@james]# chown -R oracle.dba /usr/local/ora10
[root@james]# chmod 755 /var/opt/oracle
您生成了oracle的运行时路径,并且授写权限给oracle用户,执行权限给dba组。
1.5 设置内核参数
1.5.1 修改sysctl.conf
添加如下的行到/etc/sysctl.conf中:
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
注:shmmax是一个很重要参数,根据您的机器的内存来设定。如果您设置不合适的
话,在创建数据库到约76%的时候就会挂掉。祝您好运。^_^
1.5.2 修改limits.conf
添加下面的行到/etc/security/limits.conf以修改你的资源限制:
oracle soft nofile 65536
oracle hard nofile 65536
oracle soft nproc 16384
oracle hard nproc 16384
1.5.3 让修改生效
修改了以上文件后,您必须让其生效,您重启系统,或者用以下的方式改变内核运
行参数:
[root@james]# echo 250 32000 100 128 > /proc/sys/kernel/sem
[root@james]# echo 536870912 > /proc/sys/kernel/shmmax
[root@james]# echo 4096 > /proc/sys/kernel/shmmni
[root@james]# echo 2097152 > /proc/sys/kernel/shmall
[root@james]# echo 65536 > /proc/sys/fs/file-max
[root@james]# echo 1024 65000 > /proc/sys/net/ipv4/ip_local_port_range
1.6 设置Oracle用户环境
以oracle用户登录:
%su – oracle
修改~/.bash_profile文件,去掉下列三行的注释符,使.bashrc文件生效:
#if [ -f ~/.bashrc ]; then
# . ~/.bashrc
#fi
添加下列行到~/.bashrc:
# oracle 10g
export ORACLE_BASE=/usr/local/ora10
export ORACLE_HOME=/usr/local/ora10/product/10.1.0
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/Apache/Apache/bin:$PATH
export ORACLE_OWNER=oracle
export ORACLE_SID=compiere
export ORACLE_TERM=xterm
# Edit paths
export LD_LIBRARY_PATH=/usr/local/ora10/product/10.1.0/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/ora10/product/10.1.0/bin:$PATH
# Set DISPLAY
export DISPLAY="127.0.0.1:0.0"
我是将上面的内容保存到另一个文件中,.bash_oracle,然后在.bashrc中使用
source .bash_oracle进行调用 的。您可以根据您的好恶进行设置。您需要注意的
是,ORACLE_BASE和ORACLE_HOME的设置一定得和您在前面创建的目录相符。
ORACLE_SID是默认数据库的名称,在本文档中,我们假设默认的数据库名叫
compiere,如果您想用其他的名字,请您作相应的修改。
在有些文档中,还建议您需要设置一些其他的内核参数。但是我在安装的时候,没
有设置。我的内核是2.6.8。
差别忘记,您还得把. bash_profile文件中的umask=022这一行前的注释符去掉。
1.7 设置DISPLAY
我想您肯定是不想以Oracle用户登录,启动X窗口来进行安装的啦。如果您想直接以
oracle用户启动X,进行安装,您可以忽略这一步。
我们假设我们以一个普通用户james来启动gnome。那么,如果您要以oracle用户的
身份来进行安装,则您必须首先启用X的TCP/IP连接。
Debian下默认关闭了TCP/IP连接,所以首先要打开X的TCP/IP连接。
在/etc/X11/xinit/xserverrc文件中,您将会看到下面这一行:
exec /usr/bin/X11/X -dpi 100 -nolisten tcp
去掉其中的nolisten,然后重启就OK了。
作为普通用户,打开TCP/IP连接后可能连不上X服务器。需要在用户
的.bashrc(/home/james/)中添加下面这一行:
alias startx='startx -- -deferglyphs 16'
然后,您切换到root用户下,添加127.0.0.1的X连接权限:
shell$sudo su -
shell#xhost +127.0.0.1
然后,您就可以继续下一步啦。
请注意:如果您重启系统后,必须 再次执行
xhost +127.0.0.1
2 执行安装
2.1 交换分区的调整
差点忘了,为了安装Oracle 10g,oracle推荐至少512M内存和至少400M交换空间。内
存,好象不够关系也不大,但是交换分区 呢,您还是大方一点吧。如果您的交换分区
不够400M,那么您还是先看看这一步吧。
重设交换分区可以使用如下操作:
shell# dd if=/dev/zero of=tmp_swap bs=1k count=900000
shell# chmod 600 tmp_swap
shell# mkswap tmp_swap
shell# swapon tmp_swap
完成安装以后,可以释放这个空间:
shell# swapoff tmp_swap
shell# rm tmp_swap
count值是根据您需要调整的交换分区大小而定。
2.1 运行Installer
终于可以安装了。我们假设下载的安装文件位于/home/oracle下,名称为
ship.db.cpio.gz
shell#su - oracle
shell>gunzip ship.db.cpio.gz # 目录下会生成ship.db.cpio文件
shell>cpio -idmv < ship.db.cpio # 执行完以后,会生成Disk1目录
shell>cd Disk1
shell>./runInstaller -ignoreSysPrereqs # 因为我们是在debian下,所以必须忽
略系统检测
接下的一般选择默认设置就可以了。
注意:
A.安装过程中,会提示让您以root用户执行相应的脚本,请您必须选以root身份执
行完脚本,然后继续安装。
B.创建数据时请选择编码需要选"Unicode standard UTF-8 AL32UTF8"。如果您不设
定 UTF 8的编码格式,则您在后面汉化Compiere的时候将会出错。
3 数据库设置
数据库要正常启动,包括两个方面:启动数据库实例,启动侦听。
您可以手动的启动数据库实例,但是我们推荐您用dbstart命令来启动数据库实例。
以dbstart启动数据库实例需要做如下两步操作:
A、需要修改/etc/oratab,将想自动启动的数据库(compiere)所在行的"N"修改为
"Y"。
B、cp $ORACLE_BASE/admin/compiere/pfile/initcompiere.oraXXX
$ORACLE_HOME/dbs/initcompiere.ora
其中XXX为一长串字符串,随机产生。
然后执行dbstart就可以自动启动了。然后使用lsnrctl启动侦听。
4 常见问题
暂无

compiere 常见144个问答

問: Compiere 基於什麼技術平臺開發?
答: Compiere 基於 Java 平臺開發而成,使用的應用伺服器和資料庫伺服器分別為 JBoss 和 Oracle。因此,Compiere 的伺服器端與用戶端均具備跨平臺的優勢。
問: Compiere 支援哪些資料庫,是否資料庫無關?
答: 目前,Compiere 只支援 Oracle 資料庫。Compiere 使用的嵌入式事務處理,主要在 DB/2 和 Oracle 這樣的資料庫中才支援。Compiere 2.5.2e 尚不支援 PostgreSQL、MySQL 等資料庫系統。
問題是:真的有此需要嗎?Compiere 免費,Oracle Standard Edition One 永久授權適用於 Oracle 9iR2 和 Oracle 10g,授權費用為 $149 每用戶或 $4,995 每處理器(至多2處理器)。
Compiere 未來版本將支援更多的資料庫和應用伺服器。
問: Compiere 可以執行於哪些作業系統?
答: Compiere 可執行於任何啟用 Java 的作業平臺,包括 Windows、Unix、Linux 和 Mac 等。
問: Compiere 使用了哪些軟體發展工具?
答: 在原型開發階段,使用了 Visual J++ 與 SQL Server。
隨後的正式版本遷移至 Sun Java 1.4 和 Oracle 9i 資料庫上來,且基於 J2EE 開發,用到了 Rational、Embarcadero 的工具和 JBuilder 整合開發環境。現整合開發環境已經由 JBuilder 遷移至 Open Source 的 Eclipse。
問: Compiere 支援的 Oracle 資料庫版本有何要求?
答: Compiere 2.5.2e 及以後版本,要求使用 Oracle 10g。
問: Compiere 安裝步驟有詳細的說明嗎?
答: 有。詳細的安裝指南,請參見這裏。
問: Compiere 的客制與擴展有教程說明嗎?
答: Compiere 的客制與擴展,包括一般客制、增加額外的資料欄位、增加額外的業務邏輯、新功能、介面、新報表等。一般性的指導請參見這裏,更多的實施客制請參見這裏,更多的開發客制請參見這裏。
問: Compiere 的原始碼編譯,在你們公司內部由什麼工具完成?
答: 我們內部使用的 Compiere 原始碼編譯工具是 Eclipse(參考站點),但您也可使用其他任何 Java IDE(例如免費開發工具 Sun NetBeans 和商業開發工具 Borland JBuilder)。
問: Compiere 是否提供 Java 編程文檔?
答: Compiere 原始碼中有豐富的文檔說明(英文)。
我們為金牌合作夥伴提供完整的 Java API 應用編程介面的中文文檔。
問: Compiere 是否提供資料庫建模的文檔?
答: 您可下載資料庫模型檔(ER Studio 6 格式),或使用您喜歡的資料庫建模工具將 Compiere 資料庫反向工程,得到 Compiere 資料庫模型。
我們為金牌合作夥伴提供完整的資料庫 E-R 模型的中文文檔。
問: Compiere 使用的應用伺服器 JBoss 的版本是多少?
答: 目前最新的穩定版 Compiere 2.5.2e,Compiere Server 所使用的 JBoss 為 JBoss (MX MicroKernel) [3.2.3 (build: CVSTag=JBoss_3 _2_3 date=200311301445)] 版。
問: Compiere 的語言包對伺服器端和用戶端的作業系統語言有何要求?
答: Compiere 的語言包(如簡體中文、繁體中文、日文等亞洲語種)要求 Oracle 資料庫的字元集為 Unicode,請參考 Compiere 安裝指南中關於 Oracle 安裝的指導說明。無論 Compiere 伺服器端所執行的作業系統是何語言版本,均可將 Compiere 語言包正常安裝匯入。
Compiere 用戶端所執行的作業系統語言不必與相應的語言包相對應。例如,Compiere 伺服器端(執行於 Windows 2000 Server 英文版)上安裝了簡體中文語言包,而 Compiere 用戶端執行于繁體中文的 Windows XP Professional 上,那麼只要在繁體中文 Windows XP Professional 的語言顯示設置中選擇了「簡體中文」,即可正常使用簡體中文介面(可以輸入繁體中文的資料)。
如果在 Compiere 伺服器端同時安裝簡體中文和繁體中文語言包,則無論簡體中文、繁體中文還是英文的用戶端作業系統(Windows 2000/XP/Linux 等),都可看到自己所選擇的用戶介面語言。
問: Compiere Server 能否執行為 NT Service?
答: 可以。Compiere 2.5.0d 及更高版本均直接支援以 NT Service 方式執行 Compiere Server(JBoss應用伺服器)。
安裝 - 在 %Compiere_Home\utils\windows 目錄下,執行 Windows_Service_Install.bat 腳本即可將 Compiere Server 安裝為 NT Service。安裝完成後,您可以在 Windows NT/2000 的 Services MMC(「服務」管理控制臺)中看到 Compiere 服務。
卸載 - 如果要卸載 NT Service,只需執行 Windows_Service_Uninstall.bat 腳本即可。
注意,只有 Compiere 2.5.0d 及更高版本中存在 utils\windows 目錄。如果您使用的是較低版本,請將 Compiere 2.5.0d 或更高版本中的 utils\windows 目錄複製到您的相應目錄下,同樣可使用此方法將 Compiere Server 執行為 NT Service。
問: Compiere Server 能否執行為 Linux Daemon
答: 可以。請參考 Linux Daemon 編寫文檔。
問: Compiere 原始碼中各工程的編譯(Build)順序是什麼?
答: Compiere 原始碼中各工程的編譯(Build)順序如下:
Looks、data、db、jboss、tools、dbport、print、base、ServerApps、server、interfaces、serverRoot、extend、client、install、webStore、doc。
問: 中文語言包安裝以後,為什麼主功能表的根節點「Menu」仍然是英文?
答: 該節點不是翻譯項,因此它不屬於語言包。
如果您需要將根節點的「Menu」字樣更改為中文,請執行功能表命令總體規則→系統規則→樹與節點圖片,更改「Menu」的名稱為「功能表」或「菜單」( 繁體或簡體,與使用的語言包相對應)即可。
問: Compiere 的 Web 用戶端默認超時時間能否修改,以免自動註銷?
答: 可以。請查找 serverApps\src\main\servlet\org\compiere\www 目錄下的 WEnv.java 文件,並定位至:
/** 超時 - 15 分鐘 */
public static final int TIMEOUT = 15*60;
修改上面的代碼,再重新編譯原始碼。然後重新執行 RUN_setup 腳本(需停止 Compiere Server),再啟動 Compiere Server 即可工作。
問: Compiere 的原始碼如何下載?
答: 您可在源碼與工具下載頁面找到原始碼本地下載的鏈結。
或者,您可使用如下的 CVS 下載命令:
下載 Compiere Source 2.5.2c 版本
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/compiere co -r release_252c compiere-all
下載 Compiere Source 最新版
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/compiere co compiere-all
下載 Compiere Source 指定日期戳下的版本
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/compiere co -D 2003-11-30 compiere-all
更多的 CVS 幫助,請參看 CVS 手冊和 CVS 常見問題解答。
問: Compiere 的功能覆蓋已經非常多,但如果我們需要擴展 Compiere,應該如何做呢?
答:
如果您需要客制 Compiere,無論是現有功能還是全新的功能,通常不需要編寫 Java 程式。詳細的步驟請見實施培訓課程 (詳情請參閱合作夥伴權益)。
如果需要增加新的業務邏輯規則,則只需通過 Process/Callout 技術編寫原始碼並重新編譯即可完成。您可以使用 Open Source 的整合開發環境 Eclipse,或 Borland JBuilder 這樣的商業開發工具。
問: Compiere 能夠跨 Internet 部署嗎?
答:
Compiere 的用戶端有 Web 和 Application(應用程式)兩種。雖然 Web 版本對 Internet 存取沒有問題,但截止 2.5.2e 版本 Web 用戶端仍然處於 Beta 測試階段,因此我們推薦用戶使用全功能的應用程式用戶端。
Compiere 應用程式用戶端支援跨 Internet 部署,讓您的用戶在任何地點、任何時間都可登入 Compiere 系統。
問: 聽說執行於 JVM(Java 虛擬機)上的應用程式速度較慢,不知 Compiere 用戶端應用程式是否較慢?
答:
Compiere 的 用戶端應用程式使用了快取記憶體(Cache)技術,大大加速了視窗的開啟速度。用戶在首次開啟某視窗時,稍慢一些,但再次開啟該視窗的速度則大大加快。另外,用戶通常會在工作時將自己最常用的視窗一直保持開啟狀態,以提高工作效率。隨著電腦速度的不斷提高, 以 Intel P4 2.0 GHz CPU、256 MB 記憶體的桌面 PC 為例,其執行 Compiere 用戶端應用程式的速度與 Microsoft Office 的回應速度基本無異。
問: Compiere 解決方案是否支援負載均衡(Load Balancing)?
答:
Compiere 系統可以支援負載均衡。應用伺服器 JBoss 可配置為支援 Cluster,Oracle 伺服器也可配置為 Cluster。但在實際使用中較少用到。事實上,一台 Pentium 4 2.4GHz CPU、1 GB 記憶體、7200 RPM IDE 硬碟的 PC 上同時安裝應用伺服器和資料庫伺服器,一般可以支援50個以上的併發用戶數。
如果需要支援上百個甚至數百個的併發用戶數,則需要對 Oracle 和 JBoss 的性能調優。
問: Compiere 是否提供調試追蹤資訊?
答:
Compiere 提供 Trace Log,並有不同的 Level 可供選擇。
問: 原始碼確實是完整的嗎?
答:
是的,原始碼確實完整、無隱瞞。與其他聲稱 Open Source 的 ERP 或 CRM 相比,Compiere 未將任何重要業務邏輯或系統邏輯封裝於二進位元件之中,提供 100% 的原始碼。
您可以編譯從 CVS 上所下載的特定版本的原始碼(請參閱源碼與工具),所得到的 Compiere 部署檔與直接下載的 Compiere 安裝包除 jar 檔簽名不同外,其他完全相同。
問: Compiere 可以脫離 JBoss 執行嗎?
答:
Compiere 2.5.2x 將支援應用伺服器無關的特性,屆時您可以部署其他應用伺服器。
目前,會計、請求、計畫、預警等相關功能需要 JBoss 伺服器(即 RUN_Server2 腳本執行)。工作流引擎也在 JBoss 伺服器上實現。因此,您應當在使用 Compiere 系統時保持 RUN_Server2 處於執行狀態。
問: 在 Linux 下如何設置 JAVA_HOME 環境變數?
答:
您需要編輯路徑變數。您也應當在系統變數清單中看到它。只需附加下述指定的行至您的路徑變數:%JAVA_HOME%/bin。
以 Redhat Linux 為例,要設置 JAVA_HOME 及路徑變數,請執行:
編輯用戶主目錄(即 /home/username )下的 .cshrc 和/或 .bashrc;
檢查 JAVA_HOME 及 PATH 變數是否被正確導出。在該檔中,應當有類似這樣的行:
- export JAVA_HOME *您的 Java SDK 安裝目錄* (即 /usr/j2sdk1.4.2_04)
- export PATH *您的 Java SDK 安裝所對應的 bin 目錄* (即 /usr/j2sdk1.4.4_04/bin:${PATH}
問: 252e 版本的主要更新是什麼?未來何時推出 QuickIT 實施工具包?
答:
請參見 Compiere 版本發佈說明。
我們會在 Compiere 每個新的穩定版本面世的同時,發佈對應版本的 QuickIT 實施工具包。
問: 我知道 Compiere 使用開放原始碼的應用伺服器 JBoss,不知能否部署於 WebLogic/WebSphere 平臺?
答:
Compiere 捆綁了免費、高性能的 JBoss 應用伺服器。截止 Compiere 2.5.2e,WebLogic/WebSphere 應用伺服器尚不在支援之列。
問: Compiere 資料庫邏輯模型是否存在可線上查看的版本?
答:
您可下載 Compiere 的資料庫 E-R 模型。該模型使用 E/R Studio 6 維護。
問: Compiere 支援將銷售訂單轉換為生產訂單嗎?
答:
從 Compiere 2.5.2e 開始,已經提供了從銷售訂單生成生產訂單的功能。
問: Compiere 支援 從生產訂單創建領料單嗎?
答:
從 Compiere 2.5.2e 開始,已經提供了從生產訂單(生產計畫)創建領料單的功能。
問: 在安裝 Oracle 時設置的 System 帳戶口令忘記了,但 RUN_setup 對話方塊中需要填寫,怎麼辦呢?
答:
如果您的確忘記了 Oracle 安裝過程中曾設置的 System 帳戶口令,可使用以下步驟創建新的 Oracle 實例,而無需重新安裝 Oracle:
1. 從開始功能表程式中,啟動 Configuration and Migration Tools --> Database Configuration Assistant(資料庫配置助手);
2. Database Configuration Assistant 嚮導的步驟:創建資料庫 --> General Purpose --> TNS & SID --> 專用或共用 --> 字元集選擇為 Unicode --> 完成;
3. 注意記住輸入的 System 帳戶口令,這在 RUN_setup(「Compiere 伺服器設置」)對話方塊中需要用到。
問: Compiere 應用字典的首碼是什麼含義?
答:
下面的對照表供您參考:
AD_ 應用字典
A_ 資產管理
C_ 實體功能
GL_ 總帳
I_ 匯入
K_ 知識庫
M_ 物料管理
PA_ 績效分析
R_ 請求
RV_ 報表查看器
S_ 服務管理
T_ 臨時
W_ 網上商店
X_ 生成的模型

問: 如何知道 Compiere 應用伺服器(JBoss)是否啟動成功?
答:
JBoss 啟動成功後,您在命令提示視窗中應當看到類似下面的一行:
16:14:40,093 INFO [Server] JBoss (MX MicroKernel) [3.2.3 (build: CVSTag=JBoss_3
_2_3 date=200311301445)] Started in 48s:390ms
問: Compiere Application 能否跨 Internet 部署?
答:
可以。可使用 VPN(虛擬專用網)、Citrix 或 Windows 終端技術部署應用程式用戶端。
問: 當首次登入 Compiere 用戶端應用程式時,需要填寫 Oracle 資料庫用戶名與密碼。這是否不安全?
答:
您不必擔心這個問題。用戶端配置連接參數時,並不需要輸入 Oracle 用戶名與密碼:
安裝好 Compiere 伺服器端後,您應當執行 utils\RUN_Server2 腳本啟動應用伺服器。
您在用戶端設置連接參數時,只需要輸入應用伺服器名稱。如果您在 RUN_setup 過程中修改了默認的1099埠號,則還應當輸入埠號。
點擊測試應用伺服器方塊之後,Oracle 用戶名和密碼會被自動填充。應用伺服器與資料庫伺服器兩個方塊均出現綠色的勾狀。
現在,您可以登入 Compiere 用戶端了。
問: 我使用附件功能時,確定或取消時會彈出一個錯誤消息,提示某字體目錄下的檔不存在。如何解決?
答:
您可下載附件字體補丁,並釋放到消息提示的路徑下,即可解決。
問: Compiere 應用伺服器監控功能如何登入?
答:
通過 http://servername:port/monitor 的 http 驗證登入時,使用 Compiere 的系統管理員帳號與密碼(如默認情形下的 System/System)。登入之後,您會看到這樣的畫面。
問: 中文案例資料庫是否適用於 Oracle 9iR2?
答:
Compiere 2.5.2e 及更高版本,中文案例資料庫支援的資料庫包括 Oracle 10g,詳見安裝說明。
問: Compiere 如果實現資料庫無關,是否意味著會完全丟棄 Oracle 存儲過程?
答:
當前的 Compiere 的確用到了 Oracle 的存儲過程。在資料庫無關的過程中,這些業務邏輯會全部轉移到中間件(應用伺服器)上,使得可以部署于支援 ANSI SQL 92 的絕大部分資料庫。
問: Oracle 資料庫在商業場合使用需要購買授權,它的價格是否較高?
答:
使用 Oracle Standard Edition One 授權方案,10用戶永久授權只需約¥12,500,每處理器永久授權(不限用戶數)只需約¥41,500。
建議30用戶以上的情形購買每處理器的授權方案。Oracle Standard Edition One 授權方案適用於所有作業系統平臺上的 Oracle 9i R2 和 Oracle 10g 版本。
問: Compiere 伺服器端可以部署於哪些作業系統?
答:
以 Compiere 2.5.2e 為例,伺服器端(應用伺服器和 Oracle 資料庫)可以部署的平臺包括但不限於:
Windows - Windows NT/2000/XP/2003。
Linux - Fedora Core 3.0/4.0、RHEL 3.0/4.0 AS/ES/WS、SUSE Linux Professional 9
Unix - Solaris (X86/SPARC)
對於專用於部署 Compiere 伺服器的電腦選用何種作業系統,綜合考慮授權費用、維護成本和可靠性,我們推薦:
Windows 平臺 - Windows Server 2003, Web Edition
Linux 平臺 - Redhat Enterprise Linux 3 AS
問: Compiere 的 AD(應用字典)技術有何價值?
答:
簡單來說,AD(應用字典)技術可用於兩個方面:
非編程客制:無需編寫程式,直接在 Compiere 系統實體中客制全新功能,並與現有功能整合
代碼擴展:借助於統一的 AD 技術框架,快速創建新的業務邏輯,無需消耗用戶介面的開發時間
事實上,90% 以上的業務功能客制都可以通過非編程客制完成。有關使用 AD 技術的詳盡範例和技巧,請參考 Compiere 實施顧問培訓課程。有關使用 AD 架構擴展複雜應用的文檔,請參考 Compiere 開發人員參考大全。
問: Compiere 是否提供提醒功能?
答:
是的。您可以定義需要在何種情形下被提醒,Compiere 會在條件滿足時自動發送包含詳細資訊的電子郵件,已定義好的用戶則收到提醒。有關提醒設定,請見 Compiere 中文用戶指南。
問: 我們需要使用 Compiere 完成我們的所有管理,其中就包括客戶訂購,我們的客戶包括某行業的全部企業,數量在萬家乃至十萬家以上。請問 Compiere 能否同時支援如此眾多的用戶?
答:
如果必須讓數萬客戶通過 Internet 線上登入、查詢和提交業務往來的單據(如報價單、銷售訂單、發貨單),則不推薦使用 Compiere,請評估 SAP、Oracle E-Business Suite 或 Siebel 等解決方案。
Compiere 對超過1000個併發用戶的支援,需要特別的優化,因此我們不推薦用戶在這種高容量業務需求下使用 Compiere。
問: Compiere 什麼時候支援資料庫無關和應用伺服器獨立?
答:
從 Compiere 2.5.2x 版開始,將逐步引入對資料庫無關和應用伺服器獨立的支援。
問: Compiere 是否支援 Java SDK 1.5?
答:
截至 Compiere 2.5.2e,我們建議使用 Java SDK 1.4.2_08。
問: 我們需要客制新的 Master/Detail 型別的視窗,能否提供範例代碼?
答: 金牌合作夥伴可以獲得這樣的範例代碼及技術開發支援,在合作夥伴專區線上提問即可。
問: 我公司有較多分支機搆,除少量報表外不允許功能上的客制。Compiere 能夠做到嗎?
答: 可以。Compiere 的角色授權可以防止業務功能上的隨意客制。
問: 總部及閘店之間發生採購關係,門店產生採購訂單,總部則產生了銷售訂單;還有其他反向單據如發貨單/收貨單、應收/應付的處理。Compiere 的會計模組能夠自動過帳處理嗎?
答: 可以,Compiere 支援(自動)反向單據。會計分錄自動過帳時,借項和貸項(Dr/Cr)是相反的。
問: 分公司、辦事處的能否獨立核算,生成各分支機搆在某段時間內的收支報表?
答: 可以。Compiere 報表完全支援這樣的統計分析。
問: Compiere 今後將支援哪些資料庫?
答: Compiere 今後將陸續支援 Sybase ASE、Microsoft SQL Server、IBM DB2、Cloudscape(開放原始碼)等資料庫。

星期六, 十二月 30, 2006

8086寄存器

代码段

+-------+<--- CS
| 指令 |
+-------+
| 指令 |
+-------+<--- IP
| 指令 |
+-------+
| …… |
+-------+ 数据段

+-------+<--- DS
| 数据 |
+-------+
| 数据 |
+-------+<--- SI (DI)
| 数据 |
+-------+
| …… |
+-------+ 堆栈段

+-------+<--- SS
| 栈帧 |
+-------+
| 栈帧 |
+-------+<--- BP
| 栈帧 |
+-------+
| …… |<--- SP
+-------+


汇编是最底层的计算机语言,写汇编程序就是在对内存和寄存器操作。以上描述的代码段、数据段、堆栈段都是指内存中某段区域。当程序编译时,编译器会把程序中的代码分配到不同的内存区域。这时,代码段和数据段在内存中的位置和宽度都已固定好, 而堆栈段只有起始位置,没有实际的内容,在运行时根据数据动态伸缩,因此,它是运行时系统很重要的一个部分。存放在内存中的(注意,指令在没有被CPU处理时,只是一串字符)都是数据。

内存有了数据,这时就要用到寄存器。所有的指令运算都要经过CPU中的运算器,而运算器并不知道要处理的数据在哪,因此,寄存器就扮演了数据定位的角色。寄存器也是CPU的一部分,它就专门在内存中找数据,然后告诉运算器做处理。这一过程,有个专门的术语叫“寻址”。

这里并不对所有的寄存器做介绍,只说明一些最常用的。图中用箭头表示的都是寄存器。这些都由CPU指定了特定的功能,不能作其它用途。CS和IP这两个寄存器只负责在代码段寻址,CS定位到了代码段,IP定位到具体的指令。原先说过,在内存中的都是数据,当IP有所指向的时候,数据变成了可以执行的程序,交付运算器执行。CS的地址由系统来指定。IP的控制权不在用户,而是CPU本身。DS和SI、DI负责数据段寻址,数据段是保存全局并赋值的数据的地方。SI用于读数据,DI用于写数据。DS也是由系统指定,其中的数据读取有专门的寻址方法(见gas初级教程中的寻址一节和其它的实例代码)。SS由系统维护的堆栈段首地址,初始时SP、BP和SS处于同一位置。堆栈是一动态内存区域,它的伸展方向是从高地址向低地址方向延伸。因此,高地址处叫做“栈底”,低地址处叫做“栈顶”。SP是堆栈指针,始终指向栈顶,由它来负责栈的伸缩。在函数调用时,函数中的数据都在堆栈中,BP就用来限制只能读取函数内部的数据。每个函数的调用,都用一个帧框表示,通过不同的帧框来区分不同的函数,BP就在帧框中移动。

还有AX、BX、CX、DX四个通用寄存器,它们在一般情况下可任意使用。但在一些指令中会有特别说明其中的特殊用途(请查看CPU指令手册)。

货殖列传序

《老子》一书中说:“最清平的政治达到顶峰,(应该是)邻近国家的居民可以互相望见,鸡犬的声音也能互相听到,百姓们各自品尝着甘甜的食品,穿戴着美丽的服装,习惯于安宁的风俗,从事于快乐的职业,直至老死之时也不相互往来。”如果一定要按照这种方式去生活,那么,对于近世来说,无疑等于堵塞了人民的耳目,(实际上)则是行不通的。

太史公认为:说到神农氏以前的情况,我不知道。至于象《诗经》与《书经》上所描述的虞舜以及夏朝以来的情况,则是人们总是要使自己的耳目尽情地得到音乐和女色的享受,使口中尽多地品尝牲畜肉类的美味,身躯尽量安处于舒适而快乐的环境,而精神上还要炫耀自己的权势与才能的荣耀,使这种风俗浸染百姓的思想已经很悠久了,即使用老子那样微妙的言辞逐家逐户地去劝说他们,终究也不能使他们的精神淳化。所以,(掌权者对于人民),最高明的办法是听其自然,其次是诱导他们,再其次是教育他们,又其次是(用典章制度来)束缚他们,最愚蠢的办法是与百姓争利。

太行山以西饶有木材、竹子、楮木、野麻、旄牛尾和玉石,太行山以东多出鱼、盐、漆、丝和音乐、女色,江南盛产楠木、梓木、生姜、木犀、金、锡、铅矿石、丹砂、犀牛角、玳瑁、珠玑、兽角、皮革,龙门山、碣石山以北广产马、牛、羊、毛毡、毛皮和兽筋、兽角,铜、铁则往往在千里山峦中布满,如同摆满棋子的棋盘一般。这还仅仅是物产分布的大概情况。这些物品都是中原人民所喜爱的,是百姓们衣着饮食与养生送死所必备的东西。所以,人们依赖农民耕种来供给他们食物,虞人开出木材来(供给他们使用),工匠做成器皿来(供他们的所需),商人输通这些财物(供他们选购)。这难道还需要政令教导、征发人民如期集会来完成吗?人们各自以自己的才能来行事,竭尽自己的力量,以此来满足自己的欲望。因此,物价低廉,他们就寻求买货的门路,物价昂贵,他们就寻求销售的途径,各自勤勉而致力于他们的本业,乐于从事自己的工作,如同水向低处流,日日夜夜而永无休止,他们不待召唤自己就赶来,物产不须征求而百姓们自己就生产出来。这难道不是合乎规律的而自然就是如此的证明吗?

《周书》上说:“农民不生产出来粮食,食物就要匮乏,工匠不生产出器物,劳动与生活就要陷于困厄,商人不进行流通,那么粮食、器物、财富就要断绝,虞人不开发山泽,资源就会缺少。”反过来,资源缺少,山泽也就不能重新得到开发。这四种行业,是人民衣着食物的源泉。源泉广阔,就会富饶起来;源泉窄小,就会贫穷下去。它们对上可以使国家富强,对下可以使家族富有。贫富的形成,没有入能给予他们,也没有人能剥夺他们,只是聪明的人能使财富有余,愚蠢的人只能使财物不足。所以姜太公吕望被封在营丘,那里的土地本来是盐碱地,人口稀少,于是姜太公就鼓励女子纺绩,极力提倡工艺技巧,把鱼、盐运到别处去销售。这样,其他地方的人民归附于他,货物也源源不断地运来了,象钱串一般,络绎不绝,又如车辐一般,向这里集中。所以,齐国生产的帽子、带子,衣服、鞋子畅销天下,从海滨到泰山之间的诸侯都整好衣袖来齐国朝拜。此后,齐国中经衰落,管仲又修治姜太公的事业,设立调整物价的九个官府,而齐桓公因此能够称霸天下,多次以霸主的雄姿盟会诸侯,匡正了整个天下的政治,而管仲自己也修筑了三归台,他的地位在陪臣之列,财富却胜于列国的君王。从此,齐国又富强起来,一直持续到齐威王、齐宣王时期。

 所以说:“仓库充实了,百姓才能懂得礼节,衣食丰富了,百姓才知道荣耀与耻辱。”礼仪产生于富有而废弃于贫穷。所以,君子富有了,喜欢行仁德之事,小人富有了,就把力量用在适当的地方。潭渊深了,里面就会有鱼,山林深了,野兽就会到那里去,人民富了,仁义也就归附于他们了。富有者得势,越加显赫;失势了,客人也就没有去处,因此也就心情不快。谚语说:“千金之家的子弟就不会因犯法而死于市井。”这并不是空话。所以说: “天下之人,熙熙壤壤;为利而来,为利而往。”即使有千乘兵车的天子,有万家封地的诸侯,有百室封邑的大夫,尚且担心贫穷,何况编在户口册子上的普通百姓呢!


货殖列传第六十九

范君石 译注

【说明】这是专门记叙从事“货殖”活动的杰出人物的类传。也是反映司马迁经济思想和物质观的重要篇章。“货殖”是指谋求“滋生资货财利”以致富而言。即利用货物的生产与交换,进行商业活动,从中生财求利。司马迁所指的货殖,还包括各种手工业,以及农、牧、渔、矿山、冶炼等行业的经营在内。翦伯赞曾高度评价司马迁“以锐利的眼光,注视着社会经济方面,而写成其有名的《货殖列传》”。钱钟书在论及司马迁这篇《货殖列传》时说:“当世法国史家深非史之为‘大事记 ’体者,专载朝政军事,而忽诸民生日用;马迁传《游侠》已属破格,然尚以传人为主,此篇则全非‘大事记’、‘人物志’,于新史学不啻乎辟鸿濛矣。”(《管锥篇·史记会注考证》)总之,史学界公认:“历史思想及于经济,是书盖为创举。”

《太史公自序》曰:“布衣匹夫之人,不害于政,不妨百姓,取之于时而息财富,智者有采焉。作《货殖列传》”。这十分明确而简要地道出了写作本篇的动机与主旨。全文主要是为春秋末期至秦汉以来的大货殖家,如范蠡、子贡、白圭、猗顿、卓氏、程郑、孔氏、师氏、任氏等作传。通过介绍他们的言论、事迹、社会经济地位,以及他们所处的时代、重要经济地区的特产商品、有名的商业城市和商业活动、各地的生产情况和社会经济发展的特点,叙述他们的致富之道,表述自己的经济思想,以便“后世得以观择”。太史公认为,自然界的物产是极其丰富的,社会经济的发展是不以人的意志为转移的,商业发展和经济都市的出现是自然趋势,人们没有不追求富足的。“农不出则乏其食,工不出则乏其事,商不出则三宝绝,虞不出则财匮少。”所以,他主张应根据实际情况,任商人自由发展,引导他们积极进行生产与交换,国家不必强行干涉,更不要同他们争利。这集中反映了他反对“重本抑末”,主张农工商虞并重,强调工商活动对社会发展的作用,其产生是社会发展的必然;肯定工商业者追求物质利益的合理性与合法性;突出物质财富的占有量最终决定着人们的社会地位,而经济的发展则关乎到国家盛衰等经济思想和物质观。在当时历史条件下,司马迁就能注意社会的经济生活,并认识到生产交易和物质财富的重要性,这是非常难能可贵的。

此传记天时、地理、人物、风情,历历如画。虽属说理文章,读来却颇有兴味。方家学者对此有口皆碑。潘吟阁赞曰:“《货殖传》一篇,讲的是种种社会的情形,且一一说明它的原理。所写的人物,又是上起春秋,下至汉代。所写的地理,又是北至燕、代,南至儋耳。而且各人有各人的脚色,各地有各地的环境。可当游侠读,可当小说读。读中国书而未读《史记》,可算未曾读书;读《史记》而未读《货殖传》,可算未读《史记》。美哉《货殖传》!”(《史记货殖列传新诠·编者弁言》)李景星评本传为:“举生财之法,图利之人,无贵无贱,无大无小,无远无近,无男无女,都纳之一篇之中,使上下数百年之贩夫竖子,伧父财奴,皆赖以传,几令人莫名其用意所在。……盖财货者,天地之精华,生民之命脉,困迫豪杰,颠倒众生,胥是物也。”(《史记评议》卷四)这些赞语准确而深刻地揭示了史公之识,卓绝千古;史公之笔,精妙绝伦。总揽全文可见,传中人物各具特色,各怀其才;篇中叙事行云流水,自然流畅;文中说理鞭辟入里,无懈可击;全篇辞章奇传雄浑,波澜壮阔。可谓博大精深,浑然一体,实为中华优秀传统文化中璀璨夺目的光辉篇章。

老子说:“太平盛世到了极盛时期,虽然邻近的国家互相望得见,鸡鸣狗吠之声互相听得到,而各国人民却都以自家的饮食最甘美,自己的服装最漂亮,习惯于本地的习俗,喜爱自己所事行业,以至于老死也不互相往来。”到了近世,如果还要按这一套去办事,那就等于堵塞人民的耳目,几乎是无法行得通。
太史公说:神农氏以前的情况,我不了解。至于像《诗》、《书》所述虞舜、夏朝以来的情况则是人们耳目总要听到最好听,看到最好看的,口胃总想尝遍各种肉类的美味,身体安于舒适快乐的环境,心中又夸耀有权势、有才干的光荣。统治者让这种风气浸染百姓,已经很久了,即使用老子的这些妙论挨门逐户地去劝说开导,终不能感化谁。所以,最好的办法是听其自然,其次是随势引导,其次是加以教诲,再次是制定规章制度加以约束,最坏的做法是与民争利。

太行山以西盛产木材、竹子、楮木、野麻、旄牛尾、玉石;太行山以东多有鱼、盐、漆、丝、美女;江南出产楠木、梓树、生姜、桂花、金、锡、铅、朱砂、犀牛、玳瑁、珠子、象牙兽皮;龙门、碣石山以北地区盛产马、牛、羊、毡裘、兽筋兽角;铜和铁则分布在周围千里远近,山中到处都是,有如棋子满布。这是关于各地物产分布的大致情况。这些都是中国人民所喜好的,习用的穿着、饮食、养生、送死之物。所以,人们要靠农民耕种,取得食物,要靠虞人进山开采、渔夫下水捕捉,获得物品,要靠工匠制造,取得器具,要靠商人贸易,流通货物。这难道还需要官府发布政令,征发百姓,限期会集吗?人们都凭自己的才能,竭尽自己的力量,来满足自己的欲望。所以,低价的货物能够高价出售,高价的货物能够低价购进。人们各自努力经营自己的本业,乐于从事自己的工作,就像水从高处流向低处那样,日日夜夜没有休止的时候,不用招唤便会自动前来,不用请求便会生产出来。这难道不是符合规律而得以自然发展的证明吗?

《周书》里说:“农民不种田,粮食就会缺乏;工匠不做工生产,器具就会缺少;商人不做买卖,吃的、用的和钱财这三种宝物就会断绝来路;虞人不开发山泽,资源就会短缺,资源匮乏了,山泽就不能进一步开发。”农、工、商、虞这四个方面,是人民衣食的来源。来源大则富裕,来源小则贫困;来源大了,上可以富国,下可以富家。或贫或富,没有谁能剥夺或施予,但机敏的人总是财富有余,而愚笨的人却往往衣食不足。所以,姜太公被封在营丘时,那里本来多是盐碱地,人烟稀少,于是姜太公便鼓励妇女致力于纺织刺绣,极力提倡工艺技巧,又让人们把鱼类、海盐返运到其他地区去,结果别国的人和财物纷纷流归于齐国,就像钱串那样,络绎不绝,就像车辐那样,聚集于此。所以,齐国因能制造冠带衣履供应天下所用,东海、泰山之间的诸侯们便都整理衣袖去朝拜齐国。后来,齐国中途衰落,管仲重新修治姜太公的事业,设立管理财政的九个官府,使齐桓公得以称霸,多次以霸主身份会合诸侯,使天下政治得到匡正;而管仲本人也有了三归台,官位虽只是陪臣,却比各国的君主还要富有。从此,齐国富强,一直延续到威王、宣王之时。

所以说:“粮仓充实了,百姓就会懂得礼节;衣食丰足了,百姓就会知道荣辱。”礼产生于富有,而废弃于贫穷。因此,君子富有了,就喜好去做仁德之事;小人富有了,就会随心所欲地做他能做的事。江河深,鱼就在那里生存;山林深,野兽就在那里藏身;人富有了,仁义就会依附于他。富有者得了势越发显赫,失了势,依附于他的宾客也便无处容身,因而心情不快。夷狄那里,这种情况更为突出。谚语说:“家有千金的人,不会犯法受刑死于闹事。”这不是空话。所以说:“天下之人,熙熙攘攘,都是为利而来,为利而往。”那些拥有千辆兵车的天子,享有万户封地的诸侯,占有百室封邑的大夫。尚且担心贫穷,何况编入户口册内的普通老百姓呢!

从前,越王勾践被围困在会稽山上,于是任用范蠡、计然。计然说:“知道要打仗,就要做好战备;了解货物何时为人需求购用,才算懂得商品货物。善于将时与用二者相对照,那么各种货物的供需行情就能看得很清楚。所以,岁在金时,就丰收;岁在水时,就歉收;岁在木时,就饥馑;岁在火时,就干旱。旱时,就要备船以待涝;涝时,就要备车以待旱,这样做符合事物发展的规律。一般说来,六年一丰收,六年一干旱,十二年有一次大饥荒。出售粮食,每斗价格二十钱,农民会受损害;每斗价格九十钱,商人要受损失。商人受损失,钱财就不能流通到社会;农民受损害,田地就要荒芜。粮价每斗价格最高不超过八十钱,最低不少于三十钱,那么农民和商人都能得利。粮食平价出售,并平抑调整其他物价,关卡税收和市场供应都不缺乏,这是治国之道。至于积贮货物,应当务求完好牢靠,没有滞留的货币资金。买卖货物,凡属容易腐败和腐蚀的物品不要久藏,切忌冒险囤居以求高价。研究商品过剩或短缺的情况,就会懂得物价涨跌的道理。物价贵到极点,就会返归于贱;物价贱到极点,就要返归于贵。当货物贵到极点时,要及时卖出,视同粪土;当货物贱到极点时,要及时购进,视同珠宝。货物钱币的流通周转要如同流水那样。”勾践照计然策略治国十年,越国富有了,能用重金去收买兵士,使兵士们冲锋陷阵,不顾箭射石击,就像口渴时求得饮水那样,终于报仇雪耻,灭掉吴国,继而耀武扬威于中原,号称“五霸”之一。

范蠡既已协助越王洗雪了会稽被困之耻,便长叹道:“计然的策略有七条,越国只用了其中五条,就实现了雪耻的愿望。既然施用于治国很有效,我要把它用于治家。”于是,他便乘坐小船漂泊江湖,改名换姓,到齐国改名叫鸱夷子皮,到了陶邑改名叫朱公。朱公认为陶邑居于天下中心,与各地诸侯国四通八达,交流货物十分便利。于是就治理产业,囤积居奇,随机应变,与时逐利,而不责求他人。所以,善于经营致富的人,要能择用贤人并把握时机。十九年期间,他三次赚得千金之财,两次分散给贫穷的朋友和远房同姓的兄弟。这就是所谓君子富有便喜好去做仁德之事了。范蠡后来年老力衰而听凭子孙,子孙继承了他的事业并有所发展,终致有了巨万家财。所以,后世谈论富翁时,都称颂陶朱公。

子贡曾在孔子那里学习,离开后到卫国做官,又利用卖贵买贱的方法在曹国和鲁国之间经商,孔门七十多个高徒之中,端木赐(即子贡)最为富有。孔子的另一位高徒原宪穷得连糟糠都吃不饱,隐居在简陋的小巷子里。而子贡却乘坐四马并辔齐头牵引的车子,携带束帛厚礼去访问、馈赠诸侯,所到之处,国君与他只行宾主之礼,不行君臣之礼。使孔子得以名扬天下的原因,是由于有子贡在人前人后辅助他。这就是所谓得到形势之助而使名声更加显著吧?
白圭是西周人。当魏文侯在位时,李克正致力于开发土地资源,而白圭却喜欢观察市场行情和年景丰歉的变化,所以当货物过剩低价抛售时,他就收购;当货物不足高价索求时,他就出售。谷物成熟时,他买进粮食,出售丝、漆;蚕茧结成时,他买进绢帛绵絮,出售粮食。他了解,太岁在卯位时,五谷丰收;转年年景会不好。太岁在午宫时,会发生旱灾;转年年景会很好。太岁在酉位时,五谷丰收;转年年景会变坏。太岁在子位时,天下会大旱;转年年景会很好,有雨水。太岁复至卯位时,他囤积的货物大致比常年要增加一倍。要增长钱财收入,他便收购质次的谷物;要增长谷子石斗的容量,他便去买上等的谷物。他能不讲究吃喝,控制嗜好,节省穿戴,与雇用的奴仆同甘共苦,捕捉赚钱的时机就像猛兽猛禽捕捉食物那样迅捷。因此他说:“我干经商致富之事,就像伊尹、吕尚筹划谋略,孙子、吴起用兵打仗,商鞅推行变法那样。所以,如果一个人的智慧够不上随机应变,勇气够不上果敢决断,仁德不能够正确取舍,强健不能够有所坚守,虽然他想学习我的经商致富之术,我终究不会教给他的。”因而,天下人谈论经商致富之道都效法白圭。白圭大概是有所尝试,尝试而能有所成就,这不是马虎随便行事就能成的。
猗顿是靠经营池盐起家。而邯郸郭纵以冶铁成就家业,其财富可与王侯相比。

乌氏倮经营畜牧业,等到牲畜繁殖众多之时,便全部卖掉,再购求各种奇异之物和丝织品,暗中献给戎王。戎王以十倍于所献物品的东西偿还给他,送他牲畜,牲畜多到以山谷为单位来计算牛马的数量。秦始皇诏令乌氏倮位与封君同列,按规定时间同诸大臣进宫朝拜。而巴郡寡妇清的先祖自得到朱砂矿,竟独揽其利达好几代人,家产也多得不计其数。清是个寡妇,能守住先人的家业,用钱财来保护自己,不被别人侵犯。秦始皇认为她是个贞妇而以客礼对待她,还为她修筑了女怀清台。乌氏倮不过是个边鄙之人、畜牧主,巴郡寡妇清是个穷乡僻壤的寡妇,却能与皇帝分庭抗礼,名扬天下,这难道不是因为他们富有吗?

汉朝兴起,天下统一,便开放关卡要道,解除开采山泽的禁令,因此富商大贾得以通行天下,交易的货物无不畅通,他们的欲望都能满足,汉朝政府又迁徙豪杰、诸侯和大户人家到京城。
关中地区从汧、雍二县以东至黄河、华山,膏壤沃野方圆千里。从有虞氏、夏后氏实行贡赋时起就把这里作为上等田地,后来公刘迁居到邠,周太王、王季迁居岐山,文王兴建丰邑,武王治理镐京,因而这些地方的人民仍有先王的遗风,喜好农事,种植五谷,重视土地的价值,把做坏事看得很严重。直到秦文公、德公、穆公定都雍邑,这里地处陇、蜀货物交流的要道,商人很多。秦献公迁居栎邑,栎邑北御戎狄,东通三晋,也有许多大商人。秦孝公和秦昭襄王治理咸阳,汉朝藉此做为都城;长安附近的诸陵,四方人、物辐凑集中于此,地方很小,人口又多,所以当地百姓越来越玩弄奇巧,从事商业。关中地区以南则有巴郡、蜀郡。巴蜀地区也是一片沃野,盛产栀子、生姜、朱砂、石材、铜、铁和竹木之类的器具。南边抵御滇、僰,僰地多出僮仆。西边邻近邛、笮,笮地出产马和旄牛。然而巴蜀地区四周闭塞,有千里栈道,与关中无处不通,唯有褒斜通道控扼其口,勾联四方道路,用多余之物来交换短缺之物。天水、陇西、北地和上郡与关中风俗相同,而西面有羌中的地利,北面有戎狄的牲畜,畜牧业居天下首位。可是这里地势险要,只有京城长安要约其通道。所以,整个关中之地占天下三分之一,人口也不过占天下十分之三;然而计算这里的财富,却占天下十分之六。

古时,唐尧定都河东晋阳,殷人定都河内殷墟,东周定都河南洛阳。河东、河内与河南这三地居于天下的中心,好像鼎的三个足,是帝王们更迭建都的地方,建国各有数百年乃至上千年,这里土地狭小,人口众多,是各国诸侯集中聚会之处,所以当地民俗为小气俭省,熟悉世故。杨与平阳两邑人民,向西可到秦和戎狄地区经商,向北可到种、代地区经商。种、代在石邑以北,地靠匈奴,屡次遭受掠夺。人民崇尚强直、好胜,以扶弱抑强为己任,不愿从事农商诸业。但因邻近北方夷狄,军队经常往来,中原运输来的物资,时有剩余。当地人民强悍而不务耕耘,从三家尚未分晋之时就已经对其慓悍感到忧虑,而到赵武灵王时就更加助长了这种风气,当地习俗仍带有赵国的遗风。所以杨和平阳两地的人民经营驰逐于其间,能得到他们所想要的东西。温、轵地区的人民向西可到上党地区经商,向北可到赵、中山一带经商。中山地薄人多,在沙丘一带还有纣王留下的殷人后代,百姓性情急躁,仰仗投机取巧度日谋生。男子们常相聚游戏玩耍,慷慨悲声歌唱,白天纠合一起杀人抢劫,晚上挖坟盗墓、制作赝品、私铸钱币;多有美色男子,去当歌舞艺人。女子们常弹奏琴瑟,拖着鞋子,到处游走,向权贵富豪献媚讨好,有的被纳入后宫,遍及诸侯之家。
然而邯郸也是漳水、黄河之间的一个都市。北面通燕、涿,南面有郑、卫。郑、卫风俗与赵相似,但因地靠梁、鲁,稍显庄重而又注重节操。卫君曾从濮上的帝丘迁徙到野王,野王地区民俗崇尚气节,扶弱抑强,这是卫国的遗风。
燕国故都蓟也是渤海、碣石山之间的一个都市。南面通齐、赵,东北面与胡人交界。从上谷到辽东一带,地方遥远,人口稀少,屡次遭侵扰,民俗大致与赵、代地区相似,而百姓迅速捷凶悍,不爱思考问题,当地盛产鱼、盐、枣、栗。北面邻近乌桓、夫余,东面处于控扼秽貊、朝鲜、真番的有利地位。
洛阳东去可到齐、鲁经商,南去可到梁、楚经商。所以泰山南部是鲁国故地,北部是齐国故地。
齐地被山海环抱,方圆千里一片沃土,适宜种植桑麻,人民多有彩色丝稠、布帛和鱼盐。临淄也是东海与泰山之间的一个都市。当地民俗从容宽厚,通情达理,而又足智多谋,爱发议论,乡土观念很重,不易浮动外流,怯于聚众斗殴,而敢于暗中伤人,所以常有劫夺别人财物者,这是大国的风尚。这里士、农、工、商、贾五民俱备。
而邹、鲁两地滨临洙水、泗水,还保存着周公传留的风尚,民俗喜好儒术,讲究礼仪,所以当地百姓小心拘谨。颇多经营桑麻产业,而没有山林水泽的资源。土地少,人口多,人们节剑吝啬,害怕犯罪,远避邪恶。等到衰败之时,人们爱好经商追逐财利,比周地百姓还厉害。

从鸿沟以东,芒山、砀山以北,直到巨野,这是过去梁、宋的地方。陶邑、睢阳也是都会。以前,唐尧兴起于成阳,虞舜在雷泽打过鱼,商汤曾定都于毫。这里的民俗还存有先王遗风,宽厚庄重,君子很多,喜好农事,虽然没有富饶的山河物产,人们却能省吃俭用,以求得财富的积蓄。

越、楚地带有西楚、东楚和南楚三个地区的不同风俗。从淮北沛郡到陈郡、汝南、南郡,这是西楚地区。这里民俗慓悍轻捷,容易发怒,土地贫瘠,少有蓄积。江陵原为楚国国都,西通巫县、巴郡,东有云梦,物产富饶。陈在楚、夏交接之处,流通鱼盐货物,居民多经商。徐、僮、取虑一带的居民清廉苛严,信守诺言。
彭城以东,包括东海、吴、广陵一带,这是东楚地区。这里风俗与徐、僮一带相似。朐、缯以北,风俗与齐地相同。浙江以南风俗与越地相同。吴地从吴王阖闾、楚春申君和汉初吴王刘濞招致天下喜好游说的子弟以来,东有丰富的海盐,以及章山的铜矿,三江五湖的资源,也是江东的一个都市。

衡山、九江、江南、豫章、长沙一带是南楚地区。这里风俗与西楚地区大体相似。楚失郢都后,迁都寿春,寿春也是一个都市。而合肥县南有长江,北有淮河,是皮革、鲍鱼、木材汇聚之地。因与闽中、于越习俗混杂,所以南楚居民善于辞令,说话乖巧,少有信用。江南地方地势低下,气候潮湿,男子寿命不长。竹木很多。豫章出产黄金,长沙出产铅、锡。但矿产蕴藏量极为有限,开采所得不足以抵偿支出费用。九疑山、苍梧以南至儋耳,与江南风俗大体相同,其中混杂着许多杨越风俗。番禺也是当地的一个都市,是珠玑、犀角、玳瑁、水果、葛布之类的集中地。
颍川、南阳是原夏朝人居住之地。夏人为政崇尚忠厚朴实,还有先王传留下来的风尚。颍川人敦厚老实。秦朝末年,曾经迁徙不法之民到南阳。南阳西通武关、郧关,东南面临汉水、长江、淮水。宛也是一个都市。当地民俗混杂,好事。多以经商为业。居民以抑强扶弱为己任,与颍川地区相交往,所以直到现在还被称做“夏人”。
天下物产各地不均,有少有多,民间习俗各有不同,山东地区吃海盐,山西地区吃池盐,岭南和大漠以北本来也有许多地方出产盐,这方面情况大体如此。

总而言之,楚越地区,地广人稀,以稻米为饭,以鱼类为菜,刀耕火种,水耨除草,瓜果螺蛤,不须从外地购买,便能自给自足。地形有利,食物丰足,没有饥馑之患,因此人们苟且偷生,没有积蓄,多为贫穷人家。所以,江淮以南既无挨饿受冻之人,也无千金富户。沂水、泗水以北地区,适合种植五谷桑麻,饲养六畜,地少人多,屡次遭受水旱灾害,百姓喜好积蓄财物,所以秦、夏、梁、鲁地区勤于农业而重视劳力。三河地区以及宛、陈等地也是这样,再加上经商贸易。齐、赵地区的居民聪明灵巧,靠投机求财利。燕、代地区的居民能种田、畜牧,并且养蚕。
由此看来,贤能之人在朝廷上出谋划策,论辩争议,守信尽节及隐居深山之士自命清高,保全名声,他们究竟都是为着什么呢?都是为了财富。因此,为官清廉就能长久做官,时间长了,便会更加富有;商人买卖公道,营业发达,就能多赚钱而致富。求富,是人们的本性,用不着学习,就都会去追求。所以,壮士在军队中,打仗时攻城先登,遇敌时冲锋陷阵,斩将夺旗,冒着箭射石击,不避赴汤蹈火,艰难险阻,是因为重赏的驱使。那些住在乡里的青少年,杀人埋尸,拦路抢劫,盗掘坟墓,私铸钱币,伪托侠义,侵吞霸占,借助同伙,图报私仇,暗中追逐掠夺,不避法律禁令,往死路上跑如同快马奔驰,其实都是为了钱财罢了。如今赵国、郑国的女子,打扮得漂漂亮亮,弹着琴瑟,舞动长袖,踩着轻便舞鞋,用眼挑逗,用心勾引,出外不远千里,不择年老年少,招来男人,也是为财利而奔忙。游手好闲的贵族公子,帽子宝剑装饰讲究,外出时车辆马匹成排结队,也是为大摆富贵的架子。猎人渔夫,起早贪黑,冒着霜雪,奔跑在深山大谷,不避猛兽伤害,为的是获得各种野味。进出赌场,斗鸡走狗,个个争得面红耳赤,自我夸耀,必定要争取胜利,是因为重视输赢。医生方士及各种靠技艺谋生的人,劳神过度,极尽其能,是为了得到更多的报酬。官府吏士,舞文弄墨,私刻公章,伪造文书,不避斫脚杀头,这是由于陷没在他人的贿赂之中。至于农、工、商、贾储蓄增殖,原本就是为了谋求增添个人的财富。如此绞尽脑汁,用尽力量地索取,终究是为了不遗余力地争夺财物。

谚语说:“贩柴的不出一百里,贩粮的不出一千里。”在某地住上一年,就要种植谷物;住上十年,就要栽种树木;住上百年,就应招来德行。所谓德,就是人的才德名望和财物。现在有些人,没有官职俸禄或爵位封地收入,而生活欢乐富有,可与有官爵者相比,被称做“素封”。有封地的人享受租税,每户每年缴入二百钱。享有千户的封君,每年租税收入可达二十万钱,朝拜天子、访问诸侯和祭祀馈赠,都要从这里开支。普通百姓如农、工、商、贾,家有一万钱,每年利息可得二千钱,拥有一百万钱的人家,每年可得利息二十万钱,而更徭租赋的费用要从这里支出。这种人家,就能随心所欲地吃喝玩乐了。所以说陆地牧马五十匹,养牛一百六、七十头,养羊二百五十只,草泽里养猪二百五十口,水中占有年产鱼一千石的鱼塘,山里拥有成材大树一千株。安邑有千株枣树;燕、秦有千株栗子树;蜀郡、汉水、江陵地区有千株橘树;淮北、常山以南和黄河、济水之间有千株楸树;陈、夏有千亩漆树;齐、鲁有千亩桑麻;渭川有千亩竹子;还有名扬国内、万户人家的都城,郊外有亩产一钟的千亩良田,或者千亩栀子、茜草,千畦生姜、韭菜:诸如此类的人,其财富都可与千户侯的财富相等。然而这些成为富足的资本,人们不用到市上去察看,不用到外地奔波,坐在家中即可不劳而获,身有处士之名,而取用丰足。至于那些贫穷人家,父母年老,妻子儿女瘦弱不堪,逢年过节无钱祭祀祖宗鬼神、赠人路费、聚集饮食,吃喝穿戴都难以自足,如此贫困,还不感到羞愧,那就没有什么可比拟的了。所以,没有钱财只能出卖劳力,稍有钱财便玩弄智巧,已经富足便争时逐利,这是常理。如今谋求生计,谁能不冒生命危险,即可取得所需物品,那就应受到贤人的鼓励。所以,靠从事农业生产而致富为上,靠从事商工而致富次之,靠玩弄智巧、甚至违法而致富是最低下的。没有深居山野不肯做官的隐士之行,而长期处于贫贱地位,妄谈仁义,也足以值得羞愧了。

凡是编户的百姓,对于财富比自己多出十倍的人就会低声下气,多出百倍的就会惧怕人家,多出千倍的就会被人役使,多出万倍的就会为人奴仆,这是事物的常理。要从贫穷达到富有,务农不如做工,做工不如经商,刺绣织绵不如倚门卖笑,这里所说的经商末业,是穷人致富凭借的手段。在交通发达的大都市,每年酿一千瓮酒,一千缸醋,一千甔饮浆,屠宰一千张牛羊猪皮,贩卖一千钟谷物,一千车柴草,总长千丈的船只,一千株木材,一万棵竹竿,一百辆马车,一千辆牛车,一千件涂漆木器,一千钧铜器,一千担原色木器、铁器及染料,二百匹马,二百五十头牛,一千只猪羊,一百个奴隶,一千斤筋角、丹砂,一千钧绵絮、细布,一千匹彩色丝绸,一千担粗布、皮革,一千斗漆,一千瓶酒曲、盐豆豉,一千斤鲐鱼、鮆鱼,一千石小杂鱼,一千钧腌咸鱼,三千石枣子、粟子,一千件狐貂皮衣,一千石羔羊皮衣,一千条毛毡毯,以及一千种水果蔬菜,还有一千贯放高利贷的资金,促成牲畜交易的掮客或贪心的商人获利十分之三,廉正的商人获利十分之五,这一类人也可与千乘之家相比,这是大概的情况。至于其他杂业,如果利润不足十分之二,那就不是我说的好的致富行业。
请让我简略说明当代千里范围内那些贤能者之所以能够致富的情况,以便使后世的人得以考察选择。

蜀地卓氏的祖先是赵国人,靠冶铁致富。秦国击败赵国时,迁徙卓氏,卓氏被虏掠,只有他们夫妻二人推着车子,去往迁徙地方。其他同时被迁徙的人,稍有多余钱财,便争着送给主事的官吏,央求迁徙到近处,近处是在葭萌县。只有卓氏说:“葭萌地方狭小,土地瘠薄,我听说汶山下面是肥沃的田野,地里长着大芋头,形状象蹲伏的鸱鸟,人到死也不会挨饿。那里的百姓善于交易,容易做买卖。”于是就要求迁到远处,结果被迁移到临邛,他非常高兴,就在有铁矿的山里熔铁铸械,用心筹划计算,财势压倒滇蜀地区的居民,以至富有到奴仆多达一千人。他在田园水池尽享射猎游玩之乐,可以比得上国君。
程郑是从太行山以东迁徙来的降民,也经营冶铸业,常把铁器制品卖给西南地区少数民族,他的财富与卓氏相等,与卓氏同住在临邛。

宛县孔氏的先祖是梁国人,以冶铁为业。秦国攻伐魏国后,把孔氏迁到南阳。他便大规模地经营冶铸业,并规划开辟鱼塘养鱼,车马成群结队,并经常游访诸侯,借此牟取经商发财的便利,博得了游闲公子乐施好赐的美名。然而他赢利很多,大大超出施舍花费的那点钱,胜过吝啬小气的商人,家中财富多达数千金,所以,南阳人做生意全部效法孔氏的从容稳重和举止大方。

鲁地民俗节俭吝啬,而曹邴氏尤为突出,他靠冶铁起家,财富多达几万钱。然而,他家父兄子孙都遵守这样的家规:低头抬头都要有所得,一举一动都要不忘利。他家租赁、放债、做买卖遍及各地。由于这个缘故,邹鲁地区有很多人丢弃儒学而追求发财,这是受曹邴氏的影响。

齐地风俗是鄙视奴仆,而刀间却偏偏重视他们。凶恶狡猾的奴仆是人们所担忧的,唯有刀间收留使用,让他们追逐渔盐商业上的利益,或者让他们乘坐成队的车马,去结交地方官员,并且更加信任他们。刀间终于获得他们的帮助,致富达数千万钱。所以有人说:“与其出外求取官爵,不如在刀家为奴”,说的就是刀间能使豪奴自身富足而又能为他竭尽其力。

周地居民原本就很吝啬,而师史尤为突出,他以车载货返运赚钱,车辆数以百计,经商于各郡诸侯之中,无所不到。洛阳道处齐、秦、楚、赵等国的中心,街巷的穷人在富家学做生意,常以自己在外经商时间长相互夸耀,屡次路过乡里也不入家门。因能筹划任用这样的人,所以师史能致富达七千万钱。

宣曲任氏的先祖,是督道仓的守吏。秦朝败亡之时,豪杰全都争夺金银珠宝,而任氏独自用地窖储藏米粟。后来,楚汉两军相持于荥阳,农民无法耕种田地,米价每石涨到一万钱,任氏卖谷大发其财,豪杰的金银珠宝全都归于任氏,任氏因此发了财。一般富人都争相奢侈,而任氏却屈己从人,崇尚节俭,致力于农田畜牧。田地、牲畜,一般人都争着低价买进,任氏却专门买进贵而好的。任家数代都很富有。但任氏家约规定,不是自家种田养畜得来的物品不穿不吃,公事没有做完自身不得饮酒吃肉。以此做为乡里表率,所以他富有而皇上也尊重他。
边疆地区开拓之际,只有桥姚取得马千匹,牛二千头,羊一万只,粟以万钟计算。
吴楚七国起兵反叛汉朝中央朝廷时,长安城中的列侯封君要从军出征,需借贷有息之钱,高利贷者认为列侯封君的食邑都国均在关东,而关东战事胜负尚未决定,没有人肯把钱贷给他们。只有无盐氏拿出千金放贷给他们,其利息为本钱的十倍。三个月后,吴楚被平定。一年之中,无盐氏得到十倍于本金的利息,以此富致与关中富豪相匹敌。
关中地区的富商大贾,大都是姓田的那些人家,如田啬、田兰。还有韦家栗氏、安陵和杜县的杜氏,家产也达万万钱。

以上这些人都是显赫有名、与众不同的人物。他们都不是有爵位封邑、俸禄收入或者靠舞文弄法、作奸犯科而发财致富的,全是靠推测事理,进退取舍,随机应变,获得赢利,以经营商工末业致富,用购置田产从事农业守财,以各种强有力的手段夺取一切,用法律政令等文字方式维持下去,变化多端大略如此,所以是值得记述的。至于那些致力于农业、畜牧、手工、山林、渔猎或经商的人,凭籍权势和财利而成为富人,大者压倒一郡,中者压倒一县,小者压倒乡里,那更是多得不可胜数。

精打细算、勤劳节俭,是发财致富的正路,但想要致富的人还必须出奇制胜。种田务农是笨重的行业,而秦杨却靠它成为一州的首富。盗墓本来是犯法的勾当,而田叔却靠它起家。赌博本来是恶劣的行径,而桓发却靠它致富。行走叫卖是男子汉的卑贱行业,而雍乐成却靠它发财。贩卖油脂是耻辱的行当,而雍伯靠它挣到了千金。卖水浆本是小本生意,而张氏靠它赚了一千万钱。磨刀本是小手艺,而郅氏靠它富到列鼎而食。卖羊肚儿本是微不足道的事,而浊氏靠它富至车马成行。给马治病是浅薄的小术,而张里靠它富到击钟佐食。这些人都是由于心志专一而致富的。
由此看来,致富并不靠固定的行业,而财货也没有一定的主人,有本领的人能够集聚财货,没有本领的人则会破败家财。有千金的人家可以比得上一个都会的封君,有巨万家财的富翁便能同国君一样的享乐。这是否所谓的“素封”者?难道不是吗?

星期五, 十二月 29, 2006

电子技术发展的里程碑——晶体管

谈到晶体管,也许很多人会感到很陌生.然而,就是小小的晶体管的发明给电子学带来了一场革命.这场革命发展之迅速、波及范围之广泛,完全超出了人们的想象.

现在晶体管和微型电路几乎无所不能,无处不在.小到人们日常生活中的助听器、收音机、录音机和电视机,大到实验室仪器、工业生产及国防设备、计算机、机器人、宇宙飞盘等,都离不开晶体管.可以毫不夸张地说,晶体管奠定了现代电子技术的基础.

可是,晶体管究竟是什么样的?它又是怎样发明出来的?必不可少的一步——电子管的问世1883年,闻名世界的大发明家爱迪生发明了第一只白炽照明灯.电灯的发明,给一直生活在黑暗之中的人们送去了光明和温暖.就在这个过程中,爱迪生还发现了一个奇特的现象:一块烧红的铁会散发出电子云.后人称之为爱迪生效应.1884年的一天,一位叫弗莱明的英国发明家,远涉重洋,风尘仆仆地来到美国,拜会了他慕名已久的爱迪生.就在这两位大发明家的会见中,爱迪生再次展示了爱迪生效应.遗憾的是,由于当时技术条件的限制,不论是爱迪生,还是弗莱明,都对这一效应百思不得其解,不知道利用这一效应能做些什么.

20世纪初,有线电报问世了.这一发明给人们带来了很多便利.有线电报发出的信号是高频无线电波,收信台必须进行整流,才能从听筒中听出声音来.当时的整流器结构复杂,功效又差,亟待改进.正在研究高频整流器的弗莱明灵机一动,他想,如果把爱迪生效应应用在检波器上,结果会怎样呢?就这样,引出了一个新的发明.

1904年弗莱明在真空中加热的电丝(灯丝)前加了一块板极,从而发明了第一只电子管.他把这种装有两个极的电子管称为二极管.利用新发明的电子管,可以给电流整流,使电话受话器或其它记录装置工作起来.如今,打开一架普通的电子管收音机,我们很容易看到灯丝烧得红红的电子管.它是电子设备工作的心脏,是电子工业发展的起点.

弗莱明的二极管是一项崭新的发明.它在实验室中工作得非常好.可是,不知为什么,它在实际用于检波器上却很不成功,还不如同时发明的矿石检波器可靠.因此,对当时无线电的发展没有产生什么冲击.

此后不久,贫困潦倒的美国发明家德福雷斯特,在二极管的灯丝和板极之间巧妙地加了一个栅板,从而发明了第一只真空三极管.这一小小的改动,竟带来了意想不到的结果.它不仅反应更为灵敏、能够发出音乐或声音的振动,而且,集检波、放大和振荡三种功能于一体.因此,许多人都将三极管的发明看作电子工业真正的诞生起点.德福雷斯特自己也非常惊喜,认为“我发现了一个看不见的空中帝国”.电子管的问世,推动了无线电电子学的蓬勃发展.到1960年前后,西方国家的无线电工业年产10亿只无线电电子管.电子管除应用于电话放大器、海上和空中通讯外,也广泛渗透到家庭娱乐领域,将新闻、教育节目、文艺和音乐播送到千家万户.就连飞机、雷达、火箭的发明和进一步发展,也有电子管的一臂之力.

三条腿的魔术师电子管在电子学研究中曾是得心应手的工具.电子管器件历时40余年一直在电子技术领域里占据统治地位.但是,不可否认,电子管十分笨重,能耗大、寿命短、噪声大,制造工艺也十分复杂.因此,电子管问世不久,人们就在努力寻找新的电子器件.第二次世界大战中,电子管的缺点更加暴露无遗.在雷达工作频段上使用的普通的电子管,效果极不稳定.移动式的军用器械和设备上使用的电子管更加笨拙,易出故障.因此,电子管本身固有的弱点和迫切的战时需要,都促使许多科研单位和广大科学家,集中精力,迅速研制成功能取代电子管的固体元器件.

早在30年代,人们已经尝试着制造固体电子元件.但是,当时人们多数是直接用模仿制造真空三极管的方法来制造固体三极管.因此这些尝试毫无例外都失败了.

年6月的一天,在美国贝尔实验室的一个房间里,一架样式很普通的收音机正在播放着轻柔的音乐,许多参观者在它面前驻足不前.为什么大家都对这台收音机情有独钟呢?原来这是第一架不用电子管,而代之以一种新的固体元件——晶体管的收音机.虽然人们对这架收音机显露出浓厚的兴趣.然而,他们对晶体管本身却不以为然.美国《纽约先驱论坛报》的记者在报道中写道:“这一器件还在实验室阶段,工程师们都认为它在电子工业中的革新是有限的.”事实上,晶体管发明以后,在不长的时间内,它的深远影响便很快地显示出来.它在电子学领域完成了一场真正的革命.

什么是晶体管呢?通俗地说,晶体管是半导体做的固体电子元件.像金银铜铁等金属,它们导电性能好,叫做导体.木材、玻璃、陶瓷、云母等不易导电,叫做绝缘体.导电性能介于导体和绝缘体之间的物质,就叫半导体.晶体管就是用半导体材料制成的.这类材料最常见的便是锗和硅两种.

半导体是19世纪末才发现的一种材料.当时人们并没有发现半导体的价值,也就没有注重半导体的研究.直到二次大战中,由于雷达技术的发展,半导体器件—— 微波矿石检波器的应用日趋成熟,在军事上发挥了重要作用,这才引起了人们对半导体的兴趣.许多科学家都投入到半导体的深入研究中.经过紧张的研究工作,美国物理学家肖克利、巴丁和布拉顿三人捷足先登,合作发明了晶体管——一种三个支点的半导体固体元件.晶体管被人们称为“三条腿的魔术师”.它的发明是电子技术史中具有划时代意义的伟大事件,它开创了一个崭新的时代——固体电子技术时代.他们三人也因研究半导体及发现晶体管效应而共同获得1956年最高科学奖——诺贝尔物理奖.

肖克利小组与晶体管美国人威廉·肖克利,1910年2月13日生于伦敦,曾在美国麻省理工学院学习量子物理,1936年得到该校博士学位后,进入久负盛名的贝尔实验室工作.贝尔实验室是电话发明人贝尔创立的.在电子、特别在通讯领域是最有名气的研究所,号称“研究王国”.早在1936年,当时的研究部主任,后来的贝尔实验室总裁默文·凯利就对肖克利说过,为了适应通讯不断增长的需要,将来一定会用电子交换取代电话系统的机械转换.这段话给肖克利留下了不可磨灭的印象,激起他满腔热情,把毕生精力投入到推进电子技术进步的事业中.沃尔特·布拉顿也是美国人,1902年2月10日出生在中国南方美丽的城市厦门,当时他父亲受聘在中国任教.布拉顿是实验专家,1929年获得明尼苏达大学的博士学位后,进入贝尔研究所从事真空管研究工作.温文儒雅的美国人巴丁是一个大学教授的儿子,1908年在美国威斯康星州的麦迪逊出生,相继于1928年和1929年在威斯康星大学获得两个学位.后来又转入普林斯顿大学攻读固体物理,1936年获得博士学位.1945年来到贝尔实验室工作.默文·凯利是一位颇有远见的科技管理人员.他从30年代起,就注意寻找和采用新材料及依据新原理工作的电子放大器件.在第二次世界大战前后,敏锐的科研洞察力促使他果断地决定加强半导体的基础研究,以开拓电子技术的新领域.于是,1945年夏天,贝尔实验室正式决定以固体物理为主要研究方向,并为此制定了一个庞大的研究计划.发明晶体管就是这个计划的一个重要组成部分.1946年1月,贝尔实验室的固体物理研究小组正式成立了.这个小组以肖克利为首,下辖若干小组,其中之一包括布拉顿、巴丁在内的半导体小组.在这个小组中,活跃着理论物理学家、实验专家、物理化学家、线路专家、冶金专家、工程师等多学科多方面的人才.他们通力合作,既善于汲取前人的有益经验,又注意借鉴同时代人的研究成果,博采众家之长.小组内部广泛开展有益的学术探讨.“有新想法,新问题,就召集全组讨论,这是习惯”.在这样良好的学术环境中,大家都充满热情,完全沉醉在理论物理领域的研究与探索中.

开始,布拉顿和巴丁在研究晶体管时,采用的是肖克利提出的场效应概念.场效应设想是人们提出的第一个固体放大器的具体方案.根据这一方案,他们仿照真空三极管的原理,试图用外电场控制半导体内的电子运动.但是事与愿违,实验屡屡失败.

人们得到的效应比预期的要小得多.人们困惑了,为什么理论与实际总是矛盾的呢?

问题究竟出在那里呢?经过多少个不眠之夜的苦苦思索,巴丁又提出了一种新的理论——表面态理论.这一理论认为表面现象可以引起信号放大效应.表面态概念的引入,使人们对半导体的结构和性质的认识前进了一大步.布拉顿等人乘胜追击,认真细致地进行了一系列实验.结果,他们意外地发现,当把样品和参考电极放在电解液里时,半导体表面内部的电荷层和电势力发生了改变,这不正是肖克利曾经预言过的场效应吗?这个发现使大家十分振奋.在极度兴奋中,他们加快了研究步伐,利用场效应又反复进行了实验.谁知,继续实验中突然发生了与以前截然不同的效应.这接踵而至的新情况大大出乎实验者的预料.

人们的思路被打断了,制作实用器件的原计划不能不改变了,渐趋明朗的形势又变得扑朔迷离了.然而肖克利小组并没有知难而退.他们紧紧循着茫茫迷雾中的一丝光亮,改变思路,继续探索.经过多次地分析、计算、实验,1947年12月23日,人们终于得到了盼望已久的“宝贝”.这一天,巴丁和布拉顿把两根触丝放在锗半导体晶片的表面上,当两根触丝十分靠近时,放大作用发生了.世界第一只固体放大器——晶体管也随之诞生了.在这值得庆祝的时刻,布拉顿按捺住内心的激动,仍然一丝不苟地在实验笔记中写道:“电压增益100,功率增益40,电流损失1/2.5……亲眼目睹并亲耳听闻音频的人有吉布尼、摩尔、巴丁、皮尔逊、肖克利、弗莱彻和包文.”在布拉顿的笔记上,皮尔逊、摩尔和肖克利等人分别签上了日期和他们的名字表示认同.

巴丁和布拉顿实验成功的这种晶体管,是金属触丝和半导体的某一点接触,故称点接触晶体管.这种晶体管对电流、电压都有放大作用.

晶体管发明之后基于严谨的科学态度,贝尔实验室并没有立即发表肖克利小组的研究成果.他们认为,还需要时间弄清晶体管的效应,以便编写论文和申请专利.此后一段时间里,肖克利等人在极度紧张的状态中忙碌地工作着.他们心中隐藏着一丝忧虑.如果别人也发明了晶体管并率先公布了,他们的心血就付之东流了.他们的担心绝非多虑,当时许多科学家都在潜心于这一课题的研究.1948年初,在美国物理学会的一次会议上,柏杜大学的布雷和本泽报告了他们在锗的点接触方面所进行的实验及其发现.当时贝尔实验室发明晶体管的秘密尚未公开,它的发明人之一——布拉顿此刻就端坐在听众席上.布拉顿清楚地意识到布雷等人的实验距离晶体管的发明就差一小步了.因此,会后布雷与布拉顿聊天时谈到他们的实验时,布拉顿立刻紧张起来.他不敢多开口,只让对方讲话,生怕泄密给对方,支吾几句就匆匆忙忙地走开了.后来,布雷曾惋惜地说过:“如果把我的电极靠近本泽的电极,我们就会得到晶体管的作用,这是十分明白的.”由此可见,当时科学界的竞争是多么的激烈!实力雄厚的贝尔实验室在这场智慧与技能的角逐中,也不过略胜一筹.

晶体管发明半年以后,在1948年6月30日,贝尔实验室首次在纽约向公众展示了晶体管.这个伟大的发明使许多专家不胜惊讶.然而,对于它的实用价值,人们大都表示怀疑.当年7月1日的《纽约时报》只以8个句子、201个文字的短讯形式报道了本该震惊世界的这条新闻.在公众的心目中,晶体管不过是实验室的珍品而已.估计只能做助听器之类的小东西,不可能派上什么大用场.

的确,当时的点接触晶体管同矿石检波器一样,利用触须接点,很不稳定,噪声大,频率低,放大功率小,性能还赶不上电子管,制作又很困难.难怪人们对它无动于衷.然而,物理学家肖克利等人却坚信晶体管大有前途,它的巨大潜力还没有被人们所认识.于是,在点接触式晶体管发明以后,他们仍然不遗余力,继续研究.又经过一个多月的反复思索,肖克利瘦了,眼中也布满了血丝.一个念头却在心中越来越明晰了,那就是以往的研究之所以失败,根本原因在于人们不顾一切地盲目模仿真空三极管.这实际上走入了研究的误区.晶体管同电子管产生于完全不同的物理现象,这就暗示晶体管效应有其独特之处.明白了这一点,肖克利当即决定暂时放弃原来追求的场效应晶体管,集中精力实现另一个设想——晶体管的放大作用.正确的思想终于开出了最美的花朵.1948年11月,肖克利构思出一种新型晶体管,其结构像“三明治”夹心面包那样,把N型半导体夹在两层P型半导体之间.这是一个多么富有想象力的设计啊!可惜的是,由于当时技术条件的限制,研究和实验都十分困难.直到1950年,人们才成功地制造出第一个PN结型晶体管.

电子技术发展史上一座里程碑晶体管的出现,是电子技术之树上绽开的一朵绚丽多彩的奇葩.同电子管相比,晶体管具有诸多优越性:①晶体管的构件是没有消耗的.无论多么优良的电子管,都将因阴极原子的变化和慢性漏气而逐渐劣化.由于技术上的原因,晶体管制作之初也存在同样的问题.随着材料制作上的进步以及多方面的改善,晶体管的寿命一般比电子管长100到1000倍,称得起永久性器件的美名.②晶体管消耗电子极少,仅为电子管的十分之一或几十分之一.它不像电子管那样需要加热灯丝以产生自由电子.一台晶体管收音机只要几节干电池就可以半年一年地听下去,这对电子管收音机来说,是难以做到的.③晶体管不需预热,一开机就工作.例如,晶体管收音机一开就响,晶体管电视机一开就很快出现画面.电子管设备就做不到这一点.开机后,非得等一会儿才听得到声音,看得到画面.显然,在军事、测量、记录等方面,晶体管是非常有优势的.④晶体管结实可靠,比电子管可靠100倍,耐冲击、耐振动,这都是电子管所无法比拟的.另外,晶体管的体积只有电子管的十分之一到百分之一,放热很少,可用于设计小型、复杂、可靠的电路.晶体管的制造工艺虽然精密,但工序简便,有利于提高元器件的安装密度.正因为晶体管的性能如此优越,晶体管诞生之后,便被广泛地应用于工农业生产、国防建设以及人们日常生活中.1953年,首批电池式的晶体管收音机一投放市场,就受到人们的热烈欢迎,人们争相购买这种收音机.接着,各厂家之间又展开了制造短波晶体管的竞赛.此后不久,不需要交流电源的袖珍“晶体管收音机”开始在世界各地出售,又引起了一个新的消费热潮.

由于硅晶体管适合高温工作,可以抵抗大气影响,在电子工业领域是最受欢迎的产品之一.从1967年以来,电子测量装置或者电视摄像机如果不是“晶体管化”的,那么就别想卖出去一件.轻便收发机,甚至车载的大型发射机也都晶体管化了.

另外,晶体管还特别适合用作开关.它也是第二代计算机的基本元件.人们还常常用硅晶体管制造红外探测器.就连可将太阳能转变为电能的电池——太阳能电池也都能用晶体管制造.这种电池是遨游于太空的人造卫星的必不可少的电源.晶体管这种小型简便的半导体元件还为缝纫机、电钻和荧光灯开拓了电子控制的途径.从 1950年至1960年的十年间,世界主要工业国家投入了巨额资金,用于研究、开发与生产晶体管和半导体器件.例如,纯净的锗或硅半导体,导电性能很差,但加入少量其它元素(称为杂质)后,导电性能会提高许多.但是要想把定量杂质正确地熔入锗或硅中,必须在一定的温度下,通过加热等方法才能实现.而一旦温度高于摄氏75度,晶体管就开始失效.为了攻克这一技术难关,美国政府在工业界投资数百万美元,以开展这项新技术的研制工作.在这样雄厚的财政资助下,没过多久,人们便掌握了这种高熔点材料的提纯、熔炼和扩散的技术.特别是晶体管在军事计划和宇宙航行中的威力日益显露出来以后,为争夺电子领域的优势地位,世界各国展开了激烈的竞争.为实现电子设备的小型化,人们不惜成本,纷纷给电子工业以巨大的财政资助.

自从1904年弗莱明发明真空二极管,1906年德福雷斯特发明真空三极管以来,电子学作为一门新兴学科迅速发展起来.但是电子学真正突飞猛进的进步,还应该是从晶体管发明以后开始的.尤其是PN结型晶体管的出现,开辟了电子器件的新纪元,引起了一场电子技术的革命.在短短十余年的时间里,新兴的晶体管工业以不可战胜的雄心和年轻人那样无所顾忌的气势,迅速取代了电子管工业通过多年奋斗才取得的地位,一跃成为电子技术领域的排头兵.现代电子技术的基础诚然,电子管的发明使电子设备发生了革命性变化.但是电子管体大易碎,费电又不可靠.因此,晶体管的问世被誉为本世纪最伟大的发明之一,它解决了电子管存在的大部分问题.可是单个晶体管的出现,仍然不能满足电子技术飞速发展的需要.随着电子技术应用的不断推广和电子产品发展的日趋复杂,电子设备中应用的电子器件越来越多.比如二次世界大战末出现的B29轰炸机上装有1千个电子管和1万多个无线电元件.电子计算机就更不用说了.1960年上市的通用型号计算机有10万个二极管和2.5万个晶体管.一个晶体管只能取代一个电子管,极为复杂的电子设备中就可能要用上百万个晶体管.一个晶体管有3条腿,复杂一些的设备就可能有数百万个焊接点,稍一不慎,就极有可能出现故障.为确保设备的可靠性,缩小其重量和体积,人们迫切需要在电子技术领域来一次新的突破.1957 年苏联成功地发射了第一颗人造卫星.这一震惊世界的消息引起了美国朝野的极大震动,它严重挫伤了美国人的自尊心和优越感,发达的空间技术是建立在先进的电子技术基础上的.为夺得空间科技的领先地位,美国政府于1958年成立了国家航空和宇航局,负责军事和宇航研究,为实现电子设备的小型化和轻量化,投入了天文数字的经费.就是在这种激烈的军备竞赛的刺激下,在已有的晶体管技术的基础上,一种新兴技术诞生了,那就是今天大放异彩的集成电路.有了集成电路,计算机、电视机等与人类社会生活密切相关的设备不仅体积小了,功能也越来越齐全了,给现代人的工作、学习和娱乐带来了极大便利.那么,什么是集成电路呢?集成电路是在一块几平方毫米的极其微小的半导体晶片上,将成千上万的晶体管、电阻、电容、包括连接线做在一起.真正是立锥之地布千军.它是材料、元件、晶体管三位一体的有机结合.

集成电路的问世是离不开晶体管技术的,没有晶体管就不会有集成电路.本质上,集成电路是最先进的晶体管——外延平面晶体制造工艺的延续.集成电路设想的提出,同晶体管密切相关.1952年,英国皇家雷达研究所的一位著名科学家达默,在一次会议上曾指出:“随着晶体管的出现和对半导体的全面研究,现在似乎可以想象,未来电子设备是一种没有连接线的固体组件.”虽然达默的设想并未付诸实施,但是他为人们的深入研究指明了方向.

后来,一个叫基尔比的美国人步达默的后尘,走上了研究固体组件这条崎岖的小路.基尔比毕业于伊利诺斯大学电机工程系.1952年一个偶然机会,基尔比参加了贝尔实验室的晶体管讲座.富于创造性的基尔比一下子就被晶体管这个小东西迷住了.

当时,他在一家公司负责一项助听器研究计划.心系晶体管的基尔比不由自主地想把晶体管用在助听器上,他果然获得了成功.他研究出一种简便的方法,将晶体管直接安装在塑料片上,并用陶瓷密封.初步的成功使他对晶体管的兴趣与日俱增.为寻求更大的发展,基尔比于1958年5月进入得克萨斯仪器公司.当时,公司正参与美国通信部队的一项微型组件计划.基尔比非常希望能在这一计划中一显身手.强烈的自尊促使他决心凭自己的智慧和努力进入这一计划.于是,他常常一个人埋头在工厂,思考采用半导体制造整个电路的途径.记不清多少次苦苦思索,多少回实验,多少次挫折,经过长时间的孤军奋战,到1959年,一块集成电路板终于在基尔比的手中诞生了.

同年3月,这一产品被拿到无线电工程师协会上展出.得克萨斯公司当时的副总裁谢泼德自豪地宣布,这是“硅晶体管后得克萨斯仪器公司最重要的开发成果”.在晶体管技术基础上迅速发展起来的集成电路,带来了微电子技术的突飞猛进.

微电子技术的不断进步,极大降低了晶体管的成本,在1960年,生产1只晶体管要花10美元,而今天,1只嵌入集成电路里的晶体管的成本还不到1美分.这使晶体管的应用更为广泛了.

不仅如此,微电子技术通过微型化、自动化、计算机化和机器人化,将从根本上改变人类的生活.它正在冲击着人类生活的许多方面:劳动生产、家庭、政治、科学、战争与和平.

星期三, 十二月 27, 2006

分享智慧--爱因斯坦的三篇演讲



1.我的世界观

  我们这些总有一死的人的命运是多么奇特呀!我们每个人在这个世界上都只作一个短暂的逗留;目的何在,却无所知,尽管有时自以为对此若有所感。但是,不必深思,只要从日常生活就可以明白一些人,他们的喜悦和健康关系着我们自己的全部幸福;然后是为许多我们所不认识的人,他们的命运通过同情的纽带同我们密切结合在一起。我每天上百次地提醒自己:我的精神生活和物质生活都依靠着别人(包括生者和死者)的劳动,我必须尽力以同样的分量来报偿我所领受了的和至今还在领受着的东西。我强烈地向往着俭朴的生活,并且时常为发觉自己占用了同胞的过多劳动而难以忍受。我认为阶级的区分是不合理的,它最后所凭借的是以暴力为根据。我也相信,简单淳朴的生活,无论在身体上还是在精神上,对每个人都是有益的。
  我完全不相信人类会有那种在哲学意义上的自由。每一个人的行为,不仅受着外界的强迫,而且还要适应内心的必然。叔本华说:“人虽然能够做他所想做的,但不能要他所想要的。”这句话从我青年时代起,就对我是一个真正的启示;在我自己和别人生活面临困难的时候,它总是使我们得到安慰,并且永远是宽容的源泉。这种体会可以宽大为怀地减轻那种使人气馁的责任感,也可以防止我们过于严肃地对待自己和别人;它还导致一种特别给幽默以应有地位的人生观。
  要追究一个人自己或一切生物生存的意义或目的,从客观的观点看来,我总觉得是愚蠢可笑的。可是每个人都有一定的理想,这种理想决定着他的努力和判断的方向。就在这个意义上,我从来不把安逸和享乐看作是生活目的本身——这种伦理基础,我叫它猪栏的理想。照亮我的道路,并且不断地给我新的勇气去愉快地正视生活的理想,是真、善和美。要是没有志同道合者之间的亲切感情,要不是全神贯注于客观世界——那个在艺术和科学工作领域里永远达不到的对象,那么在我看来,生活就会是空虚的。人们所努力追求的庸俗的目标——财产、虚荣、奢侈的生活——我总觉得都是可鄙的。
  我对社会正义和社会责任的强烈感觉,同我显然的对别人和社会直接接触的淡漠,两者总是形成古怪的对照。我实在是一个“孤独的旅客”,我未曾全心全意地属于我的国家,我的家庭,我的朋友,甚至我最接近的亲人;在所有这些关系面前,我总是感觉到有一定距离并且需要保持孤独——而这种感受正与年俱增。人们会清楚地发觉,同别人的相互了解和协调一致是有限度的,但这不足惋惜。这样的人无疑有点失去他的天真无邪和无忧无虑的心境;但另一方面,他却能够在很大程度上不为别人的意见、习惯和判断所左右,并且能够不受诱惑要去把他的内心平衡在这样一些不可靠的基础之上。
  我的政治理想是民主主义。让每一个人都作为个人而受到尊重,而不让任何人成为崇拜的偶像。我自己受到了人们过分的赞扬和尊敬,这不是由于我自己的过错,也不是由于我自己的功劳,而实在是一种命运的嘲弄。其原因大概在于人了比较广泛的规定。在人生的丰富多彩的表演中,我觉得真正可贵的,不是政治上的国家,而是有创造性的、有感情的个人,是人格;只有个人才能创造出高尚的和卓越的东西,而群众本身在思想上总是迟钝的,在感觉上也总是迟钝的。
  讲到这里,我想起了群众生活中最坏的一种表现,那就是使我厌恶的军事制度。一个人能够洋洋得意地随着军乐队在四列纵队里行进,单凭这一点就足以使我对他轻视。他所以长了一个大脑,只是出于误会;单单一根脊髓就可满足他的全部需要了。文明国家的这种罪恶的渊藪,应当尽快加以消灭。由命令而产生的勇敢行为,毫无意义的暴行,以及在爱国主义名义下一切可恶的胡闹,所有这些都使我深恶痛绝!在我看来,战争是多么卑鄙、下流!我宁愿被千刀万剐,也不愿参预这种可憎的勾当。尽管如此,我对人类的评价还是十分高的,我相信,要由于可笑的唯我论,去拿这种思想当宝贝吧!我自己只求满足于生命永恒的奥秘,满足于觉察现实世界的神奇的结构,窥见它的一鳞半爪,并且以诚挚的努力去领悟在自然界中显示出来的那个理性的一部分,即使只是其极小的一部分,我也就心满意足了。

2.探索的动机

  这是爱因斯坦于1918年4月在柏林物理学会举办的麦克斯·普朗克六十岁生日庆祝会上的讲话。讲稿最初发表在1918年出版的《庆祝麦克斯·普朗克60寿辰:德国物理学会演讲集》。1932年爱因斯坦将此文略加修改,作为普朗克文集《科学往何处去》的序言。
  在科学的庙堂里有许多房舍,住在里面的人真是各式各样,而引导他们到那里去的动机也实在各不相同。有许多人所以爱好科学,是因为科学给他们以超乎常人的智力上的快感,科学是他们自己的特殊娱乐,他们在这种娱乐中寻求生动活泼的经验和对他们自己雄心壮志的满足;在这座庙堂里,另外还有许多人所以把他们的脑力产物奉献在祭坛上,为的是纯粹功利的目的。如果上帝有位天使跑来把所有属于这两类的人都赶出庙堂,那末聚集在那里的人就会大大减少,但是,仍然还有一些人留在里面,其中有古人,也有今人。我们的普朗克就是其中之一,这也就是我们所以爱戴他的原因。
  我很明白,我们刚才在想象随便驱逐可许多卓越的人物,他们对建筑科学庙堂有过很大的也许是主要的贡献;在许多情况下,我们的天使也会觉得难于作出决定。但有一点我可以肯定,如果庙堂里只有被驱逐的那两类人,那末这座庙堂决不会存在,正如只有蔓草就不成其为森林一样。因为,对于这些人来说,只要有机会,人类活动的任何领域都会去干;他们究竟成为工程师、官吏、商人还是科学家,完全取决于环境。现在让我们再来看看那些为天使所宠爱的人吧。
  他们大多数是相当怪癖、沉默寡言和孤独的人,但尽管有这些共同特点,实际上他们彼此之间很不一样,不象被赶走的那许多人那样彼此相似。究竟是什么把他们引到这座庙堂里来的呢?这是一个难题,不能笼统地用一句话来回答。首先我同意叔本华(Schopenhauer)所说的,把人们引向艺术和科学的最强烈的动机之一,是要逃避日常生活中令人厌恶的粗俗和使人绝望的沉闷,是要摆脱人们自己反复无常的欲望的桎梏。一个修养有素的人总是渴望逃避个人生活而进入客观知觉和思维的世界;这种愿望好比城市里的人渴望逃避喧嚣拥挤的环境,而到高山上去享受幽静的生活,在那里透过清寂而纯洁的空气,可以自由地眺望,陶醉于那似乎是为永恒而设计的宁静景色。
  除了这种消极的动机以外,还有一种积极的动机。人们总想以最适当的方式画出一幅简化的和易领悟的世界图像;于是他就试图用他的这种世界体系(cosmos)来代替经验的世界,并来征服它。这就是画家、诗人、思辨哲学家和自然科学家所做的,他们都按自己的方式去做。各人把世界体系及其构成作为他的感情生活的支点,以便由此找到他在个人经验的狭小范围理所不能找到的宁静和安定。
  理论物理学家的世界图像在所有这些可能的图像中占有什么地位呢?它在描述各种关系时要求尽可能达到最高的标准的严格精密性,这样的标准只有用数学语言才能达到。另一方面,物理学家对于他的主题必须极其严格地加以控制:他必须满足于描述我们的经验领域里的最简单事件。企图以理论物理学家所要求的精密性和逻辑上的完备性来重现一切比较复杂的事件,这不是人类智力所能及的。高度的纯粹性、明晰性和确定性要以完整性为代价。但是当人们畏缩而胆怯地不去管一切不可捉摸和比较复杂的东西时,那末能吸引我们去认识自然界的这一渺小部分的究竟又是什么呢?难道这种谨小慎微的努力结果也够得上宇宙理论的美名吗?
  我认为,是够得上的;因为,作为理论物理学结构基础的普遍定律,应当对任何自然现象都有效。有了它们,就有可能借助于单纯的演绎得出一切自然过程(包括生命)的描述,也就是说得出关于这些过程的理论,只要这种演绎过程并不太多地超出人类理智能力。因此,物理学家放弃他的世界体系的完整性,倒不是一个什么根本原则性的问题。
  物理学家的最高使命是要得到那些普遍的基本定律,由此世界体系就能用单纯的演绎法建立起来。要通向这些定律,没有逻辑的道路,只有通过那种以对经验的共鸣的理解为依据的直觉,才能得到这些定律。由于有这种方法论上的不确定性,人们可以假定,会有许多个同样站得住脚的理论物理体系;这个看法在理论上无疑是正确的。但是,物理学的发展表明,在某一时期,在所有可想到的构造中,总有一个显得别的都高明得多。凡是真正深入研究过这问题的人,都不会否认唯一地决定理论体系的,实际上是现象世界,尽管在现象和它们的理论原理之间并没有逻辑的桥梁;这就是莱布尼兹(Leibnitz)非常中肯地表述过的“先定的和谐”。物理学家往往责备研究认识论者没有给予足够的注意。我认为,几年前马赫和普朗克之间所进行的论战的根源就在于此。
  渴望看到这种先定的和谐,是无穷的毅力和耐心的源泉。我们看到,普朗克就是因此而专心致志于这门科学中的最普遍的问题,而不是使自己分心于比较愉快的和容易达到的目标上去。我常常听到同事们试图把他的这种态度归因于非凡的意志力和修养,但我认为这是错误的。促使人们去做这种工作的精神状态是同信仰宗教的人或谈恋爱的人的精神状态相类似的;他们每天的努力并非来自深思熟虑的意向或计划,而是直接来自激情。我们敬爱的普朗克就坐在这里,内心在笑我像孩子一样提着第欧根尼的灯笼闹着玩。我们对他的爱戴不需要作老生常谈的说明。祝愿他对科学的热爱继续照亮他未来的道路,并引导他去解决今天物理学的最重要的问题。这问题是他自己提出来的,并且为了解决这问题他已经做了很多工作。祝他成功地把量子论同电动力学、力学统一于一个单一的逻辑体系里。

3.培养独立工作和独立思考的人

  在纪念的日子里,通常需要回顾一下过去,尤其是要怀念一下那些由于发展文化生活而得到特殊荣誉的人们。这种对于我们先辈的纪念仪式确实是不可少的,尤其是因为这种对过去最美好事物的纪念,必定会鼓励今天善良的人们去勇敢奋斗。但这种怀念应当由从小生长在这个国家并熟悉它的过去的人来做,而不应当把这种任务交给一个像吉卜赛人那样到处流浪并且从各式各样的国家里收集了他的经验的人。
  这样,剩下来我能讲的就只能是超乎空间和时间条件的、但同教育事业的过去和将来都始终有关的一些问题。进行这一尝试时,我不能以权威自居,特别是因为各时代的有才智的善良的人们都已讨论过教育这一问题,并且无疑已清楚地反复讲明他们对于这个问题的见解。在教育学领域中,我是个半外行,除了个人经验和个人信念以外,我的意见就没有别的基础。那么我究竟是凭着什么而有胆量来发表这些意见呢?如果这真是一个科学的问题,人们也许就因为这样一些考虑而不想讲话了。
  但是对于能动的人类的事务而言,情况就不同了,在这里,单靠真理的知识是不够的;相反,如果要不失掉这种知识,就必须以不断的努力来使它经常更新。它像一座矗立在沙漠上的大理石像,随时都有被流沙掩埋的危险。为了使它永远照耀在阳光之下,必须不断地勤加拂拭和维护。我就愿意为这工作而努力。
  学校向来是把传统的财富从一代传到一代的最重要机构。同过去相比,在今天就更是这样。由于现代经济生活的发展,家庭作为传统和教育的承担者,已经削弱了。因此比起以前来,人类社会的延续和健全要在更高程度上依靠学校。
  有时,人们把学校简单地看作一种工具,靠它来把最大量的知识传授给成长中的一代。但这种看法是不正确的。知识是死的,而学校却要为活人服务。它应当在青年人中发展那些有益于公共福利的品质和才能。但这并不意味着应当消灭个性,使个人变成仅仅是社会的工具,像一只蜜蜂或蚂蚁那样。因为由没有个人独创性和个人志愿的统一规格的人所组成的社会,将是一个没有发展可能的不幸的社会。相反,学校的目标应当是培养独立工作和独立思考的人,这些人把为社会服务看作自己最高的人生问题。就我所能作判断的范围来说,英国学校制度最接近于这种理想的实现。
  但是人们应当怎样来努力达到这种理想呢?是不是要用讲道理来实现这个目标呢?完全不是。言辞永远是空的,而且通向毁灭的道路总是和多谈理想联系在一起的。但是人格绝不是靠所听到的和所说出来的言语而是靠劳动和行动来形成的。
  因此,最重要的教育方法总是鼓励学生去实际行动。初入学的儿童第一次学写字便是如此,大学毕业写博士论文也是如此,简单地默记一首诗,写一篇作文,解释和翻译一段课文,解一道数学题目,或在体育运动的实践中,也都是如此。
  但在每项成绩背后都有一种推动力,它是成绩的基础,而反过来,计划的实现也使它增长和加强。这里有极大的差别,对学校的教育价值关系极大。同样工作的动力,可以是恐怖和强制,追求威信荣誉的好胜心,也可以是对于对象的诚挚兴趣,和追求真理与理解的愿望,因而也可以是每个健康儿童都具有的天赋和好奇心,只是这种好奇心很早就衰退了。同一工作的完成,对于学生教育影响可以有很大差别,这要看推动工作的主因究竟是对苦痛的恐惧,是自私的欲望,还是快乐和满足的追求。没有人会认为学校的管理和教师的态度对塑造学生的心理基础没有影响。
  我以为对学校来说最坏的事,是主要靠恐吓、暴力和人为的权威这些办法来进行工作。这种做法伤害了学生的健康的感情、诚实的自信;它制造出的是顺从的人。这样的学校在德国和俄国成为常例;在瑞士,以及差不多在一切民主管理的国家也都如此。要使学校不受到这种一切祸害中最坏的祸害的侵袭,那是比较简单的。只允许教师使用尽可能少的强制手段,这样教师的德和才就将成为学生对教师的尊敬的唯一源泉。
  第二项动机是好胜心,或者说得婉转些,是期望得到表扬和尊重,它根深蒂固地存在于人的本性之中。没有这种精神刺激,人类合作就完全不可能;一个人希望得到他同类赞许的愿望,肯定是社会对他的最大约束力之一。但在这种复杂感情中,建设性同破坏性的力量密切地交织在一起。要求得到表扬和赞许的愿望,本来是一种健康的动机;但如果要求别人承认自己比同学、伙伴们更高明、更强有力或更有才智,那就容易产生极端自私的心理状态,而这对个人和社会都有害。因此,学校和教师必须注意防止为了引导学生努力工作而使用那种会造成个人好胜心的简单化的方法。
  达尔文的生存竞争以及同它有关的选择理论,被很多人引证来作为鼓励竞争精神的根据。有些人还以这样的办法试图伪科学地证明个人之间的这种破坏性经济竞争的必然性。但这是错误的,因为人在生存竞争中的力量全在于他是一个过着社会生活的动物。正像一个蚁垤里蚂蚁之间的交战说不上什么是为生存竞争所必需的,人类社会中成员之间的情况也是这样。
  因此,人们必须防止把习惯意义上的成功作为人生目标向青年人宣传。因为一个获得成功的人从他人那里所取得的,总是无可比拟地超过他对他们的贡献。然而看一个人的价值应当是从他的贡献来看,而不应当看他所能取得的多少。
  在学校里和生活中,工作的最重要的动机是在工作和工作的结果中的乐趣,以及对这些结果的社会价值的认识。启发并且加强青年人的这些心理力量,我看这该是学校的最重要的任务。只有这样的心理基础,才能引导出一种愉快的愿望,去追求人的最高财富——知识和艺术技能。
  要启发这种创造性的心理才能,当然不像使用强力或者唤起个人好胜心那样容易,但也正因为如此,所以才更有价值。关键在发展于孩子们对游戏的天真爱好和获得他人赞许的天真愿望,引导他们为了社会的需要参与到重要的领域中去。这种教育的主要基础是这样一种愿望,即希望得到有效的活动能力和人们的谢意。如果学校从这样的观点出发胜利完成了任务,它就会受到成长中的一代的高度尊敬,学校规定的课业就会被他们当作礼物来领受。我知道有些儿童就对在学时间比对假期还要喜爱。
  这样一种学校要求教师在他的本行成为一个艺术家。为了能在学校中养成这种精神,我们能够做些什么呢?对于这一点,正像没有什么方法可以使一个人永远健康一样,万应灵丹是不存在的。但是还有某些必要的条件是可以满足的。首先,教师应当在这样的学校成长起来。其次,在选择教材和教学方法上,应当给教师很大的自由。因为强制和外界压力无疑也会扼杀他在安排他的工作时所感到的乐趣。
  如果你们一直在专心听我的想法,那么有件事或许你们会觉得奇怪。我详细讲到的是,我认为应当以什么精神教导青少年。但我既未讲到课程设置,也未讲到教学方法。譬如说究竟应当以语文为主,还是以科学的专业教育为主?
  对这个问题,我的回答是:照我看来,这都是次要的。如果青年人通过体操和远足活动训练了肌肉和体力的耐劳性,以后他就会适合任何体力劳动。脑力上的训练,以及智力和手艺方面技能的锻炼也类似这样。因此,那个诙谐的人确实讲得很对,他这样来定义教育:“如果人们忘掉了他们在学校里所学到的每一样东西,那么留下来的就是教育。”就是这个原因,我对于遵守古典,文史教育制度的人同那些着重自然科学教育的人之间的争论,一点也不急于想偏袒哪一方。
  另一方面,我也要反对把学校看作应当直接传授专门知识和在以后的生活中直接用到的技能的那种观点。生活的要求太多种多样了,不大可能允许学校采用这样专门的训练。除开这一点,我还认为应当反对把个人作为死的工具。学校的目标始终应当是使青年人在离开它时具有一个和谐的人格,而不是使他成为一个专家。照我的见解,这在某种意义上,即使对技术学校也是正确的,尽管它的学生所要从事的是完全确定的专业。学校始终应当把发展独立思考和独立判断的一般能力放在首位,而不应当把取得专门知识放在首位。如果一个人掌握了他的学科的基础,并且学会了独立思考和独立工作,就必定会找到自己的道路,而且比起那种其主要训练在于获得细节知识的人来,他会更好地适应进步和变化。
  最后,我要再一次强调一下,这里所讲的,虽然多少带有点绝对肯定的口气,其实,我并没有想要求它比个人的意见具有更多的意义。而提出这些意见的人,除了在他做学生和教师时积累起来的个人的经验以外,再没有别的什么东西来做他的根据。

星期四, 九月 28, 2006

A short trip on the CAN bus

By Niall Murphy Embedded Systems Design
(08/11/03, 19:00:00 H EDT)
How do we reduce the amount of cabling in cars as we install more complex embedded systems? A bus architecture is the answer.

Some modern automobiles contain three miles of cabling. Because this number is liable to rise as components grow more intelligent, we'll need to find ways to reduce the amount of wiring. The sheer weight of the wiring is motivation enough for automobile manufacturers to reduce the size of the wiring loom.

While wiring weight leads to some problems, the complexity of the wiring leads to other difficulties, specifically diagnosing faults and making minor modifications. I once encountered one emergency vehicle that was abandoned because faults in its wiring harness couldn't be diagnosed and rewiring the whole vehicle would be as expensive as purchasing a new one. Reducing wiring could alleviate this problem.

Cars are not the only application domain affected by wiring weight and complexity. In some luxury yachts, manufacturers add concrete blocks to one side of the boat to compensate for the heavy wiring loom on the far side.

A bus architecture is the only way to keep the volume of wiring from becoming unmanageable. In this column, I discuss the most widely used automotive bus architecture.

CAN

The Controller Area Network (CAN) bus has come to dominate the automotive industry in Europe, and U.S. manufacturers are starting to adopt it. Hundreds of millions of CAN controllers are sold every year and most go into cars. Typically the CAN controllers are sold as on-chip peripherals in microcontrollers.

For the physical layer, a twisted pair multidrop cable is specified with a length ranging from 1,000m at 40Kbps to 40m at 1Mbps. The maximum payload of a message is 8 bytes, and all messages carry a cyclic redundancy code (CRC). Each message has an identifier, which can be interpreted differently depending on the application or higher-level protocols used. All nodes on the network receive each message and then decide whether that identifier value is of interest.

Choosing a CAN controller defines the physical and data-link portions of your protocol stack. In a closed system, you could choose to implement your own higher-level protocol. If you need to interoperate with other vehicle components, though, the vehicle manufacturer will most likely mandate that you use one of the standard higher-level protocols. For engine management, the J1939 protocol is common, while CANOpen is preferred for body management, such as lights and locks. Both buses run on the same hardware; different application-specific needs are met by the higher-level protocols.

CAN is a relatively slow medium and can't satisfy all automotive needs. For example in-car entertainment requires high-speed audio and video streaming. These needs are being addressed by Media-Oriented Systems Transport (MOST) and IDB-1394b, which is based on Firewire. Diverse requirements mean that vehicles will generally have to run more than one bus.

Where does this bus go?
The requirements of a bus in an automotive environment are different from desktop networks, where Ethernet is the technology of choice. In an embedded environment, the bus needs better real-time performance. Delays caused by the bus will only form one part of the delay, but if there's a nondeterministic component in the bus architecture, it will be impossible to completely compensate for it at higher levels.

If two Ethernet nodes start transmitting at the same time, the resulting signal on the bus is an abnormal voltage. Both nodes detect this and both nodes back-off for a random period and then try again. Neither node has priority, and so whichever node retries first will gain advantage. If the nodes clash again or clash with a third node, there will be further delay. A well-managed Ethernet network is operated well below full capacity, keeping such clashes to a minimum, but still leaving us with a nondeterministic component in our communications. Since the original clashing messages were both destroyed, this situation is sometimes referred to as destructive arbitration.

CAN takes a different approach. Every bit transmitted on the bus is defined as recessive or dominant, which maps to 1 or 0. All nodes can listen and transmit at the same time. If more than one node is transmitting, the result will carry a dominant bit if at least one node is transmitting a dominant bit. When a node transmits a dominant bit, it will see a dominant bit on the bus. In this case, the node will not know if anyone else was trying to transmit. If a node transmits a recessive bit, but a dominant bit is seen on the bus, the node knows that someone else is on the bus.

The clever part of CAN bus arbitration is the first node's decision to back off if some other node transmits a dominant bit the first time the first node sends a recessive bit. The identifier is the first part of the message transmitted; by the time the identifier has been sent, all nodes bar one will have backed off. The message identifier is sometimes called the arbitration field because it decides which messages get priority.

All nodes transmit a single dominant bit when starting a message. This is the start of message (SOM) bit. Any node just listening will see bus activity and will not attempt to start a transmission until the current packet is complete. So the only possibility for collision is between nodes that simultaneously send an SOM bit. These nodes will remain synchronized for the duration of the packet or until all but one of them backs off. After the SOM bit, the arbitration field is transmitted. The winning node will always be the one with the arbitration field of the highest value, because it's the one that will transmit a dominant bit first, while the other nodes are transmitting recessive bits. Thus, you could consider the numerical value of the arbitration field to be the priority of the message.

This is nondestructive bus arbitration, since the highest priority message doesn't get destroyed. In fact, the node transmitting that message doesn't even know that a collision happened. The only way for a node to know there is a collision is for the node to see something on the bus that's different from what it transmitted. So the successful node and any other listening nodes never see any evidence of a collision on the bus.

The highest priority message always gets through, but at the expense of the lower-priority messages. Thus, CAN's real-time properties are analogous to the properties of a preemptive real-time kernel on a single processor. In both cases, the goal is to ensure that the highest-priority work gets completed as soon as possible. It's still possible to miss a hard real-time deadline, but there should never be a case where a high priority job misses its deadline because it was waiting for a lower-priority task to complete.

If a number of nodes clash, one will win out. After that message has completed, all of the "losers" will try again. In this second round, the next highest-value arbitration field will win out, and the process will repeat. There's nothing to stop the highest-value arbitration field from being transmitted again. This is similar to the situation in a preemptive real-time kernel where a high-priority task could choose to run continuously and thereby prevent some lower-priority tasks from completing their work. In both cases, it would be bad design to lock out lower priorities in this way, but it's important to realize that the CAN bus doesn't prevent this scenario—it's the designer's responsibility to ensure that no one message type hogs the bus.

The arbitration field can be 11 or 29 bits long, depending which variation of the protocol is used. You can use the first few bits for priority and the remaining bits to identify the message type. The CAN standard doesn't dictate what meaning you attach to those bits, but the many higher-level protocols that sit on top of CAN do define them. For example, the J1939 standard allows one portion of the bits to be a destination address, since the CAN protocol itself specifies a source address for all packets, but doesn't mandate a destination address. This is quite reasonable since much of the traffic on an automotive bus consists of broadcasts of measured information, which isn't destined for one specific node.

Fault tolerance

CAN provides a number of fault tolerance mechanisms. One is the inclusion of a 2-bit acknowledgment field. During the acknowledgment time after each packet is sent, the transmitter sends a recessive bit while any receivers send a dominant bit. The transmitter can thus determine that at least one node has received the packet. This prevents a disconnected node from continuing its transmission, blissfully ignorant that no one is listening.

When the bus speed is kept below 125Kbps, the bus can use a fault-tolerant mode where the bus will function if one of the two wires is cut. The motivation for this design is that the bus may continue to operate after a car crash has severed one of the lines. One wire mode is also used if one of the lines is shorted to ground or to the supply voltage. In this mode, noise tolerance is reduced. Each node continues to monitor the faulty line and will resume dual-wire operation if the fault condition goes away.

Noise tolerance

Information is carried on the bus as a voltage difference between the two lines. If both lines are at the same voltage, the signal is a recessive bit. If the CAN_H line is higher than the CAN_L line by 0.9V, the signal line is a dominant bit. There's no independent ground reference point for these two lines. The bus is therefore immune to any ground noise, which in a vehicle can be considerable.

The signals on the two CAN lines will both be subject to the same electromagnetic influences, and so the difference in voltages between the two lines will not vary. Because of this, the bus is also immune to electromagnetic interference.

Double trouble

If two nodes are communicating, it's reasonable for the receiving node to request that a message be repeated if the first attempt is corrupted. On a CAN bus, much of the traffic is broadcast messages. Because there are many receivers, it's possible that one node will be affected by a local failure, while other nodes have successfully received the message.

For this reason, you should avoid using messages that depend on previous state or contain relative information. Consider a hypothetical message that indicates that vehicle speed has increased by 10mph. If one node receives a corrupted message and requests a repeat, some of the other nodes will receive two complete identical messages. This will lead to some receivers believing that the total change in speed was 20mph.

I consider it good practice to avoid these types of messages, regardless of the communications architecture. Messages that depend on state information make it more difficult to design one node so that it can be reset independently of the rest of the system. If a node resets and then receives a message that depends on some state information, such as the current speed, you have to ensure that this state information can be retrieved after each reset.

Event driven and time triggered

CAN is an event-driven protocol. The bus architecture doesn't impose any restrictions on when nodes are allowed to place messages on the bus. An alternative approach is a time-triggered protocol where messages have preallocated time slots. FlexRay is an example of a time-triggered automotive bus protocol. FlexRay has a maximum bandwidth of 10Mbps, and may prove to be the successor to CAN when the complexity of automotive networks leads to requirements that can't be met by CAN. However, current investment in CAN will ensure that such a transition is many years away.

While the basic CAN bus definition doesn't contain a time-triggered scheduling mechanism, the Time-Triggered CAN (TTCAN) protocol, which sits on top of standard CAN hardware, provides a mechanism for scheduling messages. You can alternatively design your own schedule if your application is running on a closed network.

In many designs, it's simpler to allow each node to send messages at arbitrary times. If you're simply transmitting a simple measured value, then the software will always read the value just when it's needed for the next transmission. However, if the message is the result of some event, such as an alarm condition, then the software is responsible for delaying that message until its slot becomes available.

One of the main motivations for time-triggered communications is that it fits well with the design of process control loops. If you need to use the velocity of a wheel as feedback for a control loop, then having a guarantee that the velocity will appear on the bus at fixed intervals means that the control loop has a fixed worst case for the latency for that data.

The hardware

Of almost 300 million CAN nodes sold last year, only 15 million were stand- alone chips. The remainder were built into microcontrollers, usually 16-bit parts. So if you are using CAN, you'll probably be programming an on-chip peripheral. No doubt some CAN peripherals are sold into applications that don't use that particular peripheral, but you can still interpret 300 million as meaning this protocol is mighty popular.

Because the CAN hardware looks after the entire packet, including CRC checks, the overhead on the processor is far less than it would be for an equivalent serial port. Failed messages are retried automatically, with no software interaction.

The CAN controller queues incoming and outgoing messages. The length of this queue will have a big impact on how long your processor can spend processing a single message. In other words, a short queue will increase the risk that you'll miss a message.

Since most CAN nodes are destined for the automotive market, battery consumption is important. For this reason most CAN controllers have a sleep mode, where they'll be awakened if a message does appear on the bus. This sort of power saving becomes important when you leave your car in an airport for two weeks, and you would like to have some juice left in the battery when you get back.

The dominator

CAN is going to dominate the automotive scene for many years to come. It's also having considerable impact in other industries where noise immunity and fault tolerance are more important than raw speed. Because CAN hardware has become so cheap and is integrated into so many microcontrollers, it's a design option well worth considering the next time you want to get your embedded systems talking to each other.

Niall Murphy has been writing software for user interfaces and medical systems for 10 years. He is the author of Front Panel: Designing Software for Embedded User Interfaces. Murphy's training and consulting business is based in Galway, Ireland. He can be reached at nmurphy@panelsoft.com. Reader feedback to this column can be found at www.panelsoft.com/murphyslaw.