Wednesday, September 02, 2009

ArduinoのPWM出力

ソフトウェアでdigitalWriteとdelayMicrosecondで行っていたが効率が悪い.MsTimer2というライブラリがあって,Arduinoの割込を簡単に利用できるのでこれもいいけど,ArduinoのanalogWriteを使ってpin 3,5,6,8,9,10,11でPWMを出力している.これらのpinを使うことにした.ただし注意しないといけないのはこれらのpinから出力されるPWMの周波数は異なる.オシロスコープでこれを確認した.

pin 3, 8, 9, 10, 11は周期約2.04msのPWMを出力するが,pin 5,6ではその半分の約1.02msの周期でPWMを出力している.持っているサーボはpin 5,6の出したPWMだと反応が遅い.ArduinoのanalogWriteのページで周波数490HzのPWMを出しているという情報はpin 3,8,9,10,11の方のことだな

Wednesday, August 26, 2009

ArmadilloではuCLinuxを使用している.uCLinuxではfork()を使用することができない!
MMU(Memory Management Unit)がないからだ.もっと早く気付けばよかったのに!
こんな常識な話知らない自分まだまだだな~

fork()の代わりにvfork()を使用できるらしいが,子プロセスがexec系,exit()を呼び出すまで親プロセスはsuspendする.これじゃマルチプロセスじゃねぇ!じゃん

まぁ,pthreadを使用することだな・・・

参考:
ソフト・マクロのCPUでLinuxを動かす(後編)OSの実装とネットワーク対応機器への応用

Thursday, August 20, 2009

標準Cライブラリの実装 strerror関数

see also: http://www.kijineko.com/doc/jsp/strerror_8c-source.html
標準Cライブラリの実装 strerror関数: "#include

char *strerror(int errnum)
{
char *result;
switch (errnum)
{
case 0:
result = 'No error';
break;
case EDOM:
result = 'Domain error';
break;
case ERANGE:
result = 'Range error';
break;
case EILSEQ:
result = 'Illegal sequence';
break;
default:
result = 'Unknown error';
break;
}
return result;
}"

Thursday, August 13, 2009

IPC - プロセス間通信に関するメモ

■ 共有メモリいろいろ
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, void *shmaddr, int shmflg);
int shmdt(void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

shmget() は共有メモリ作成
shmat() は共有メモリに読み書き許可を与える(アタッチする)
参考サイト:
*http://www.gadgety.net/shin/tips/unix/ipc/shared.html

手順:
●共有メモリを準備プロセス(アクセスもする)
shmget(): 共有メモリ作成
shmat() : 読み書き許可をアッタチ
読み書きを行い
shmdt() : 共有メモリを分離する
shmctl(): 共有メモリを破棄

●共有メモリにアクセスするプロセス
必要であれば ftok() : キーを生成 (fork()を使用して,子プロセスはいらない)
shmget() : 生成したキーから共有メモリのidを取得
shmat() : 読み書き許可をアタッチ
shmdt() : 共有メモリを分離
終わり

■ セマフォいろいろ
  • key_t ftok(const char *pathname, int proj_id)
共有メモリを使用するときこの関数を使ってキーを生成する理由についてわからなくて,調べてみた.まぁ理由は単純だけどなんでわからんかっただろう?

プロセス間通信のとき,たとえば共有メモリを使用するときとか,セマフォを使用するとき,IDを使用してアクセスするが,共通するリソースを使用したいときはプロセス(複数)みんな同じIDを使用しないとアクセスできない.この関数の引数はプロセス間の一つのプロトコルみたいなもので,みんな前もって同じpathnameとproj_idを使用してキーを生成すると決めれば,同じキーを使用することができ,共有リソースにアクセスすることができる.

参考サイト:
* http://d.hatena.ne.jp/s-kita/20080710/1215696366
* http://www.gadgety.net/shin/tips/unix/ipc/semaphore.html

■ --

■ --

■ --

Monday, July 13, 2009

ネットワークプログラミング - メモ

■ Byte order
#include <arpa/inet.h&st;
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

■ bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
struct sockaddr{
unsigned short sa_family;
char sa_data[14];
}
■ IPソケットアドレス関連の構造体
struct sockaddr_in {
sa_family_t sin_family; // address family: AF_INET
in_port_t sin_port; // port in network byte order
struct in_addr sin_addr; // internet address
}
// Internet address
struct in_addr{
uint32_t s_addr; // address in network byte order
}
※sockaddr と sockaddr_in は同じもので,互換性を保つためにある.
実際よく使うのは sockaddr_in で,sockaddr_in からIPアドレスを取得できる(struct in_addr で)

■ インターネットアドレス操作
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);

typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
}
■ gethostbyname, gethostbyaddr
#include <netdb.h>
extern int h_errno;

struct hostent *gethostbyname(const char *name);

#include <sys/socket.h>
struct hostent *gethostbyaddr(const void *addr,socklen_t len, int type);
struct hostent *gethostent(void);

struct hostent {
char *h_name; // official name of host
char **h_aliases; // alias list
int h_addrtype; // host address type
int h_length; // length of address
char **h_addr_list; // list of addresses
}
#define h_addr h_addr_list[0]

gethostbyname(), gethostbyaddr()の代わりに
getaddrinfo(3), getnameinfo(3)を使うべき
■ getaddrinfo, getnameinfo
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);

void freeaddrinfo(struct addrinfo *res);
const char *gai_strerror(int errcode);

struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};

■ shutdown() 関数
この関数を使用してTCPでコネクションを閉じるが,注意しないといけないのはこの関数は正常なコネクション切断のときにしか使えない.
例えば:クライアントから接続してきて(accept()),forkで分岐
親プロセスではクライアントのソケットは使わないため,そのソケットを閉じるべきが(変にいじってほしくないから),このときshutdown()関数を使用すると,分岐した子プロセスではそのクライアントのソケットを使えなくなる.なのでこの場合は親プロセスではshutdown()ではなく,普通にclose()関数でソケットを閉じる.