2007年9月23日 星期日

簡易版 Minicom

昨天坐車下南部,在車上心血來潮想在 NEO1973上玩Minicom 結果發現手上沒有 minicom的 package。人在車上又沒有網路…想玩東西又沒得玩…就自已寫嘍…
然後就在車上開始 coding ...
發現還蠻有趣的,大概到台中的時候完成,之後就在車上一直玩…
玩到 Notebook 沒電 @_@ 4 cell 的電池果然是不夠力啊

執行檔是 tickminicom
使用方法是 ./tickminicom [device] [speed]
default 的 device 是 /dev/ttySAC0 ,speed 是 115200
跳脫字元是 '%'

因為是自已寫的,所以可以很直接的測試幾個想知道的性質…

Filename: Makefile




CC=arm-angstrom-linux-gnueabi-gcc
all:
$(CC) -o tickminicom tick_minicom.c util.c
gcc -o tickminicom_x86 tick_minicom.c util.c



Filename: debug.h




#ifndef __MPENV_DEBUG_H__
#define __MPENV_DEBUG_H__

#include <assert.h>

#define CONFIG_DEBUG

#ifdef CONFIG_DEBUG
#include <stdio.h>
#define debug(f, a...) \
do{ \
printf ("DEBUG: (%s, %d): %s: ",__FILE__, __LINE__, __FUNCTION__); \
printf (f, ## a); \
} while (0)
#else
#define debug(f, a...)
#endif

#define error(f, a...) \
do{ \
printf ("ERROR: (%s, %d): %s: ",__FILE__, __LINE__, __FUNCTION__); \
printf (f, ## a); \
} while (0)


#endif




Filename: util.h




#ifndef __TICK_MINICOM_UTIL_H__
#define __TICK_MINICOM_UTIL_H__

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

/// Be aware 'x' cannot be a expression or this function cause unpredicable result.
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

struct bdrt {
int bps;
u_int32_t b;
};

static struct bdrt bdrts[] = {
{ 0, B0 },
{ 9600, B9600 },
{ 19200, B19200 },
{ 38400, B38400 },
{ 57600, B57600 },
{ 115200, B115200 },
{ 230400, B230400 },
{ 460800, B460800 },
{ 921600, B921600 },
};

int getche(int fd);

int open_device(char *device,int speed);

int set_baud(int fd,int rate);

#endif




Filename: util.c




#include "util.h"
#include "debug.h"
#include <string.h>

int getche (int fd) {
int i;
char ch;
struct termios old, new;
tcgetattr (fd, &old);
memcpy (&new,&old, sizeof (struct termios));
new.c_lflag = ~(ICANON | ECHO);
tcsetattr (fd, TCSANOW,&new);
i = read (fd,&ch, 1);
tcsetattr (fd, TCSANOW, &old);
if (i == 1) {
return ch;
}
else {
debug("fd %d ERROR\n",fd);
return -1;
}
}

int set_baud(int fd,int rate) {
int i,rt;
u_int32_t bd = 0;
struct termios ti;
for (i = 0; i < ARRAY_SIZE(bdrts); i++) {
if (bdrts[i].bps == rate) {
bd = bdrts[i].b;
break;
}
}
if (bd==0) {
error("Cannot set Baud Rate!!\n");
return -1;
}
rt = tcgetattr(fd, &ti);
if (rt<0) {
error ("Cannot get attr i=%d\n",rt);
return rt;
}
rt = cfsetispeed(&ti, B0);
if (rt<0) {
error("Cannot set input baud to B0!!\n");
return rt;
}
debug("Open uart with speed %d\n",bdrts[i].bps);
rt = cfsetospeed(&ti, bd);
if (rt < 0) {
error("Cannot set baud rate %d\n",bdrts[i].bps);
return rt;
}
ti.c_cflag |= CRTSCTS; // hardware control
return tcsetattr(fd, 0, &ti);
}

/**
* Open Uart for testing
* return value is the fd
*/

int open_device (char *device,int speed) {
int fd;
if (device==NULL) {
error("device is invalid (NULL pointer)\n");
return -1;
}
debug("Try to open device %s!\n",device);
fd = open(device,O_RDWR);
if (fd < 0) {
error("cannot open uart %s, fd is %d\n",device,fd);
error("%s\n",strerror(errno));
return -1;
}
if (set_baud(fd,speed) < 0) {
error("Set Baud rate failed!!\n");
return -1;
}
return fd;
}




Filename: tick_minicom.c




/**
* @file tick_minicom.c
* @brief a tiny uart client
* @license GPL (General Public License)
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "debug.h"
#include "util.h"

#define DEFAULT_UART "/dev/ttySAC0"
#define DEFAULT_BAUD 115200

static int keep_run=1;



/// Set '%' as the escape code
void input_command(int input,int output) {
int i;
char buf[1];
while(keep_run) {
i=getche(input);
if (i< 0) {
debug("file closed!!\n");
keep_run=0;
break;
}
if (i=='%') {
debug("User entered the escape code.\n");
debug("Exiting program!\n");
keep_run=0;
break;
}
buf[0]=i;
write(output,buf,1);
}
}

void read_from_uart(int input,int output) {
int i;
char buf[1];
while (keep_run) {
i=getche(input);
buf[0]=i;
i=write(output,buf,1);
}
}

int main (int args,char **argv) {
int uart;
int pid;
char buf[128];
if (args==1) {
uart=open_device(DEFAULT_UART,DEFAULT_BAUD);
} else if (args==2) {
uart=open_device(argv[1],DEFAULT_BAUD);
} else {
uart=open_device(argv[1],atoi(argv[2]));
}
if (uart<0) {
error("Open device failed !!\n");
return 0;
}else {
debug("Open Uart and set baud rate OK!!\n");
}
keep_run=1;
pid=fork();
if (pid) { // parent
input_command(0,uart);
debug("Exiting Tick's minicom\n");
}else { // child
pid = getppid();
read_from_uart(uart,1);
debug("Try to close uart\n");
debug("Result of close uart=%d\n",close(uart));
}
sprintf(buf,"kill -9 %d",pid);
system(buf);
}

2007年9月8日 星期六

MPENV

大概在一年多前使用 QT2 寫了一些Embedded System 的 MMI,
因為某些外在因素整體架構有點亂。
而在當時就開使構思寫一個精簡的 MMI Framework.
定義一些在 Embedded System MMI 的寫作方式,資源控管等東西…
目標是讓降低 Programmer 寫 MMI 時要顧慮的東西,如 status,resource,
只要專心寫要寫的東西就好了。

幾個月前和幾個朋友聊到這個想法,也就在 SourceForge 註冊了這個案子.
MPENV (Modulized Pages Environment)

簡單來說,就是用 MVC 的架構來寫一個 MMI Framework.
目前我們只定義了 Module 和 Pages 的介面及跳躍方式。
離目標還有一大段的距離。不過我們正在努力。

我們使用C++,GTK/GLib 為開發平台,目前不使用 GTKmm。
而 UI component 是用 手寫 or gtk_builder 做出來。

這幾天還在想如何把 controller 實做出來 :P

目前有一大堆手寫文件,希望在不久的將來我可以把文件整理一下寫個 SDS 再向大家介紹它。

--
文筆不好, 真是苦手啊 ~_~
ToDo: 表達能力