Monday, September 23, 2013

在linux安装 CH340/341

安装CH340/341的串口驱动时,在网上搜索到很多要自己下载源代码编译安装的方法。其实最新版本的ubuntu已经完美支持。 第一步,先找到USB设备,使用命令
lsusb
Bus 001 Device 002: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 007 Device 003: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 008 Device 002: ID 1bcf:0002 Sunplus Innovation Technology Inc. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
找到usbserial设备的信息,这里是bus 007 Bus 007 Device 003: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter 然后装入usbserial模块, 根据结果修改vendor和product参数
sudo modprobe usbserial vendor=0x1a86 product=0x7523
最后看看是否成功安装
lsmod | grep usbserial
返回结果
usbserial               37161   1 ch341
有上面一行信息意味安装成功 参考:http://forums.reprap.org/read.php?12,4546

Thursday, May 16, 2013

quine

python
a='a=%s; print( a %% repr(a))'; print( a % repr(a))
go
/* Go quine */
package main
import "fmt"
func main() {
 fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
}
var q = `/* Go quine */
package main
import "fmt"
func main() {
 fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
}
var q = `
refer to http://research.swtch.com/zip

Friday, April 26, 2013

compiler optimizations

编译优化
有一下一段简单代码
#define LED2=0x04;
#define LED3=0x40;
void toggle_led(void){
static int idx=0;
    if((++idx)&1)
        __REG_B(GPKDAT) = LED2;
    else
        __REG_B(GPKDAT) = LED3;
}
优化编译后反汇编得到的代码是:
//omit the code of testing idx,
        movne r2,#LED2
        ldrne r3,=GPKDAT
        strbne r2,[r3]
        moveq r2,#LED3
        ldreq r3,=GPKDAT
        strbeq r2,[r3]
        bx lr
我估计在编译的时候,这里的语句没办法优化因此会 3,4,6,7 行的多余出来。其实这4行用2行代码就可以了。 修改了C代码为
#define LED2=0x04;
#define LED3=0x40;
void toggle(void){
        static int idx=0;
        unigned char temp;
        if((++idx)&1)
                temp = LED2;
        else
                temp = LED3;
        __REG_B(GPKDAT) = temp;
}
代码编译后反编译:
//omit the code of testing idx
        moveq r3,#LED2
        movne r3,#LED3
        ldr  r2,=GPKDAT
        strb r3,[r2]

估计是因为宏__REG_B中使用了volatile,因此对无法代码进行优化。

Thursday, April 25, 2013

纪念驾照考试全通

最后科目4以92分优异的成绩通过。好像月底可以拿驾照。

Wednesday, April 24, 2013

S3C6410 learning note

- Timer 4

To make a timer4 module work properly, below have to be configed

TCFG0[23:16] Dead zone length
TCFG0[15:18] Prescaler 1 value for Timer 2,3 and 4
TCFG0[7:0]   Prescaler 0 value for Timer 0 and 1
I don't care the dead zone, so just set-up timer4 prescaler.
Give 0xff00 to TCFG0

TCFG1[19:16] Select Mux input for PWM Timer 4
I don't care the other setting but timer 4, choose 1/16

TCON[22]  Timer4 Auto reload on/off 0:one shot 1: interval mode(auto reload)
TCON[21]  Timer4 manual update, 0:No operation 1:Update TCNTB4
TCON[20]  Timer4 start/stop 0:stop 1:start
timer4 in interval mode,start timer4 give 101 to [22:20]

0x7f006044
TINT_CSTAT[9] Timer4 interrupt status bit. clears by writing '1' on this bit.
(INPORTANT)After every interrupt happen this bit must be clear, so clear this bit must
preform during interrupt occurred.
TINT_CSTAT[4] Timer4 interrupt enable 1: enabled 0:disabled

- Interrupts
use VIC function, 've' flag was set in coprocessor cp15
mrc p15,0,r0,c1,c0,0
orr r0,r0,#(1<<24)
mcr p15,0,r0,c1,c0,0


set all interrupts to irq use VICxINTSELECT to 0
eable int28 use VICxINTENABLE


0x71200f00
VIC0ADDRESS
(INPORTANT)this register must be written a any value after interrupt service has been done

- to be continued

Tuesday, April 23, 2013

在C++中,函数的返回引用用法

// fragment 1  
// class for tracing into the source  
class Int{  
private:  
  int _value;  
  Int(int v):_value(v){}  
  ~Int(){cout << "destructed " << _value << endl;  
}
在函数中返回一个引用的用法:例如一下的代码片段
// fragment 2
Int &returnRef(void){
  Int *pi=new Int(1);
  return *pi;
}
一般我们在一段代码中使用new创建指针对象时.都需要delete. 但是在fragment 2中并没有这样做. 因为在这里创建的对象需要被引用的方式返回.如果删除了.在后面的使用就会出现访问内存越界.
测试代码
// fragment 3  
int main(void){  
  Int i=returnRef();  
  return 0;  
}  
// result:  
// destructed 1 
从这里可以看出.在fragment 3中的变量i其实是fragment 2中的指针对象.在main中自动被系统释放了. 引用函数返回的值要赋予给实例化的变量,这是一种比较合理的使用方法.可以让系统自动释放内存.
下一步,测试一下赋值操作和初始化的分别.测试代码如下
// fragment 4  
int main(void){  
  Int i(2);  
  i=returnRef();  
  return 0;  
}  
// result:  
// destructed 2 
注意.这段代码造成了内存泄漏.,对象Int(1)的解析没有被执行.说明内存泄漏了.
再把代码改为:
// fragment 5  
int main(void){  
  Int *pi;  
  pi=&returnRef();  
  delete pi;  
  return 0;  
}  
// result:  
// destructed 1 
Int(1)被释放了.
从以上测试得出结论.函数的引用返回必须被正确的使用.否则不可避免的会发生内存泄漏.

JAVA的泛型

这里有一编刚开始学JAVA的时候些的心得06年的时候了.里面有很多想法不准确的.但是为了提醒自己.也放上来

看了几天的JAVA.在对象的容器中的那一部分时有这样的感想.
有些类的使用方法非常类似C++的类函数.如:ActionListener等使用起来感觉很爽.但是...
JAVA对在运行时实现类的对象没有C++那么灵活.给我的感觉是JAVA根本就没有实现泛型编程(Generic Programming)这个概念. 举个例子:
Java
int max(int [] obj,int length) {  
    int i,result;  
    result=obj[0];  
    for(i=1;i<length;i++) {  
        if(result<obj[i])result=obj[i];  
    }  
    return result;  
}  
  
float max(float [] obj,int length) {  
    int i;  
    float result;  
    result=obj[0];  
    for(i=1;i<length;i++) {  
        if(result<obj[i])result=obj[i];  
    }  
    return result;  
} 
但是用STL就可以这样简单的实现了.

C++
template<class T>
T max(T obj[],int length) {  
    int i;  
    T result;  
    result=obj[0];  
    for(i=1;i<length;i++) {  
        if(result<obj[i])  
            result=obj[i];  
    }  
    return result;  
}
java的那段程序只实现了int和float类的获得最大值的功能. 而且还要人工编写了2次代码.而C++那段代码就用1次代码编写. 就实现了任何重载了比较大小和赋值("<"和"=")2个操作符的类 的相同功能都实现了.
关于JAVA中的ArrayList好像是实现了泛型的概念.但是继续看下去才发现 这也是一个"伪泛型"工具.因为这个类定义的参数是Object.而JAVA中定义 类的时候如果没有指定继承的父类缺省是继承了Object这个最基本的基类.
在我印象中,面向对象的编程中,泛型编程是不可分割的一部分(这是我自己 主观认为的).难道JAVA就把OOP实现到这一步吗?

使用SAX来解析XML

在JAVA开发中有很多XML的解析API.也有很多开源工具,我以前使用最多的是apache的digester.他功能强大.应用了事件驱动的模式.可以根据rule来分别处理每一个Tag的内容.
后来研究了一下sax, 发现这已经够用了.因为一般的小应用都是把xml作为数据传输.很少用到dtd等.
这并不是介绍digester.而是介绍有java的基本API. 他就是SAX. 使用SAX就不需要额外添加包.这对于Android的开发来说会带来一定的方便,
至于DOM是一个面向树结果的xml的处理.用过程式的方式处理.代码的耦合程度高.不在讨论的范围内.
先看例程:
package com.saxtest.test;

import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XmlParseTest {
    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
        FileInputStream in=new FileInputStream("d:/test.xml");

        SAXParserFactory spf=SAXParserFactory.newInstance();
        SAXParser parser=spf.newSAXParser();
        parser.parse(in, new MyHandler());
        in.close();
    }
}

class MyHandler extends DefaultHandler{
    private int space=0;
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        for(int i=0;i<space;i++){
            System.out.print('\t');
        }
        System.out.println(qName+' '+attributes.getValue("title"));
        space ++;
    }
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        space --;
    }
    @Override
    public void characters(char[] buf, int start, int length) throws SAXException {
        StringBuilder sb=new StringBuilder();
        boolean hasContent=false;
        for(int i=0;i<length;i++){
            if(buf[start+i]=='\n')continue;
            hasContent=true;
            sb.append(buf[start+i]);
        }
        if(hasContent){
            for(int i=0;i<space;i++){
                System.out.print('\t');
            }

            System.out.println(sb);
        }
    }
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
    }
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
    }
}
基本上对于XML的处理.都可以向main方法一样不用什么变化,主要业务在MyHandler中.只需要2个方法(startElement,endElement)就把xml树中的所有节点迭代出来了.而且并不需要递归迭代.极大的优化了代码的结构.具体使用看javadoc就有很详细的解释.
SAXParser会处理每一个tag.在tag的开始会调用startElement方法.当tag结束时会调用endElement, 这种设计类似于事件驱动的设计模型.是一种很好的解耦合设计.

Monday, April 22, 2013

如何编写DLL实例,很早以前的笔记

在mingw中编写DLL程序
 * 用C++编写DLL程序
用例子来说明
dll.h
#ifndef _DLL_H_  
#define _DLL_H_  
  
#if BUILDING_DLL  
# define DLLIMPORT __declspec (dllexport)  
#else /* Not BUILDING_DLL */  
# define DLLIMPORT __declspec (dllimport)  
#endif /* Not BUILDING_DLL */  


class DLLIMPORT DllClass
{
  public:
    DllClass();
    virtual ~DllClass(void);

    void setValue(int);
    int getValue() const;
  private:  
    int _value;
};  
#endif /* _DLL_H_ */
dllmain.cpp
#include "dll.h"
#include <iostream>
#include <windows.h>

DllClass::DllClass()
{
  std::cout << "Dll class construction" << std::endl;
}


DllClass::~DllClass ()
{
  std::cout << "Dll class destruction" << std::endl;
}

void DllClass::setValue(int n){
  _value=n;
}
int DllClass::getValue() const{
  return _value;
}
BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
调用方法
main.cpp
#include "dll.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
    DllClass dc;
    dc.setValue(100);
    cout << "involved: "<<dc.getValue() << endl;
    return 0;
}
编译DLL源文件
g++.exe -c dllmain.cpp -o dllmain.o -DBUILDING_DLL=1   -g3
连接DLL源文件,并输出描述DLL的def文件和.a文件.
dllwrap.exe --output-def libdlltest.def \
            --driver-name c++ \
            --implib libdlltest.a dllmain.o \
            --no-export-all-symbols \
            --add-stdcall-alias \
            -lgmon \
            -g3 \
            -o dlltest.dll
关于DLL加载的方式有3种.
  1. 隐式, 就象使用静态库一样. 
  2. 显式, 用LoadLibrary/FreeLibrary方法来加载DLL程序. 
  3. 延迟方式, 很类似隐式,但是就并不是在程序开始运行的时候加载DLL.具体还要找更多的文档资料.

One Q, One A: How do I add syntax highlighting to my Blogger blo...

One Q, One A: How do I add syntax highlighting to my Blogger blo...: Step 1) Via Blogger's admin panel, navigate to your " Template " section Step 2) Click " Edit HTML " Step 3)...

Sunday, April 21, 2013

cross-compiler for arm on debian squeeze

在debian安装cross-compiler

这2天鼓捣交叉编译环境的安装,在网上看了很多资料。下载了gcc的源码正准备开始的时候,发现一个README.cross的文件。看了以后说之前已经有人做好发行版的预编译了。然后去这个网站一看 http://www.emdebian.org/debian/ 我靠,这有这回事。我之前辛辛苦苦把binutils编译好了。现在发现都是重复劳动。

首先添加源的keyring
apt-get install  emdebian-archive-keyring
在/etc/apt/sources.list中加入这行
deb http://www.emdebian.org/debian/ squeeze main


然后运行apt-get update 安装binutils
apt-get install binutils-arm-linux-gnueabi
安装gcc
apt-get install gcc-4.4-arm-linux-gnueabi
安装完成后,在/usr/bin会有 arm-linux-gnueabi-*的执行文件。我们可以手动修改成为arm-linux-*

Saturday, February 2, 2013

温度20左右,

今天看ARM的指令集,感觉比C语言还复杂。