Tuesday, November 5, 2013
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
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
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 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
C++
关于JAVA中的ArrayList好像是实现了泛型的概念.但是继续看下去才发现 这也是一个"伪泛型"工具.因为这个类定义的参数是Object.而JAVA中定义 类的时候如果没有指定继承的父类缺省是继承了Object这个最基本的基类.
在我印象中,面向对象的编程中,泛型编程是不可分割的一部分(这是我自己 主观认为的).难道JAVA就把OOP实现到这一步吗?
看了几天的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的处理.用过程式的方式处理.代码的耦合程度高.不在讨论的范围内.
先看例程:
SAXParser会处理每一个tag.在tag的开始会调用startElement方法.当tag结束时会调用endElement, 这种设计类似于事件驱动的设计模型.是一种很好的解耦合设计.
后来研究了一下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
main.cpp
* 用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种.- 隐式, 就象使用静态库一样.
- 显式, 用LoadLibrary/FreeLibrary方法来加载DLL程序.
- 延迟方式, 很类似隐式,但是就并不是在程序开始运行的时候加载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 update 安装binutils
这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-*
Subscribe to:
Comments (Atom)