BABY

網誌分類

谷哥廣告

gcc & g++

在 LInux Ubuntu 要如何 Complie C (使用 gcc)或者是 C++ 檔案(使用 g++)

gcc 的用法相當地多,在此只講一行的方法。就是
gcc –o output_file_name source.c
如果沒有加”-o output_file_name”這個選項的話,預設輸出會是 a.out

一般的 C 副檔名可以取名為 .c
如 hello.c

1
2
3
4
5
#include <stdio.h>

int main() {
  printf("%s","Hello World!!");
}

在 console 下打

gcc hello.c

會出現一些錯誤 , 例如找不到 stdio.h
利用 sudo find / -name stdio.h 尋找也會找不到檔案
因此需要下載 sudo apt-get install g++
complie 可打
gcc hello_c.c -o hello_c

另外一個範例為 c++
hello_cc.cc

1
2
3
4
5
6
7
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
   cout << "Hello, world!\n";
   return 0;
}

c++ 則要使用 g++ 來 complie
$ g++ -Wall hello.cc -o hello
或是分成兩行
$ g++ -Wall -c hello.cc
$ g++ hello.o (should use g++)

一個完整的範例包含 Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
main.cc
#include <iostream>
using namespace std;
// Output in print.cc
extern void Output(void);
int main(void)
{
   Output();
   return 0;
}

print.cc
#include <iostream>
using namespace std;
void Output(void)
{
   cout << "print one line!" << endl;
}

Makefile
# Makefile for printline
#
# GNU g++
#
# use gcc here for usual C Code
CC = g++
# Put the parameters for compiling the c code here
# ( -O2 is a kind of Optimization parameter )
CFLAGS = -O2
# Object Files
# ( make will automatically search the corresponding .c or .cc file for
# compiling )
OBJ = main.o print.o
all: printline
clean:
rm -f *.o core printline
printline: $(OBJ)
$(CC) $(CFLAGS) -o printline $(OBJ)

vim

在 Windows 上 Trace Code 可以使用 Source Insight
但在 Linux 上如果要 Trace Code 是否有這麼好用的軟體?
搜尋Google大神,答案或許應該是肯定的
(操作起來可能沒有 SOurce Insight 這麼方便)

Vim……
安裝可以操考以下幾個 Blog
1.http://c9s.blogspot.com/2007/07/vim-taglist-plugin.html
2.http://andrewtw.wordpress.com/2006/12/25/gvim-%E5%A5%BD%E7%8E%A9%E8%80%B6%EF%BD%9E/
3.http://walkingice.twbbs.org/blog/?p=167
4.http://nixchun.pixnet.net/blog/post/21765036

當然也可以參考 Vim 官網
http://vim-taglist.sourceforge.net/installation.html

只要照著步驟安裝都可以成功

Linux Build Driver Modules Makefiles

1
2
3
4
5
6
7
8
9
10
11
#KERNELDIR ?= /usr/src/linux

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m += hidsample2.o

all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:

make -C $(KERNELDIR) M=$(PWD) clean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* -------------------------------------------------------------------------- */
/* ----- err_t FFTransform(sig_t *,unsigned long,vector_t *,vector_t *) ----- */
/* -------------------------------------------------------------------------- */
/*
 * Performs FFT on "signal" x:
 *
 *    - Truncate or pad with zeros if npts != in-&gt;n
 *    - Copy truncated/padded x-&gt;n to real part and set imaginary part to 0.0
 *    - Call mixfft [fft()]
 *    - Write phase and modulus to the output vectors
 *
 * Either modul or phase can be NULL if one is not
 * interested in this result.
 *
 * Note that "signal" may not be a signal, but it can be
 * LPCOEFF vector hidden in a sig_t structure!
 */
err_t FFTransform(sig_t *x,unsigned long npts,vector_t *modul,vector_t *phase)
{
  int i,j;
  float tmp[MAX_FFT_SIZE];

  /*
   * Check that (nearly) all is OK!
   */
  if(npts &gt; MAX_FFT_SIZE) {
    gerror(FFT_LENGTH_ERR,"FFTransform(): FFT length too large (npts= %d, max= %d)",
       npts,MAX_FFT_SIZE);
    return(FFT_LENGTH_ERR);
  }
  if(frexp((double)npts,&amp;i) != (double)0.5) {
    gerror(FFT_LENGTH_ERR,"FFTransform(): FFT length (%d) is not a power of two",
       npts);
    return(FFT_LENGTH_ERR);
  }
  if(x-&gt;n == 0 || npts == 0) {
    gerror(ZERO_LENGTH_WARN,"FFTransform(): zero length signal (nb. samples= %d, npts= %d)",
       x-&gt;n,npts);
    DONE;
  }
  if(modul)
    if(modul-&gt;n &lt; npts/2) {
      gerror(OUT_SIZE_ERR,"FFTransform(): not enough memory allocated to module vector");
      return(OUT_SIZE_ERR);
    }
  if(phase)
    if(phase-&gt;n &lt; npts/2) {
      gerror(OUT_SIZE_ERR,"FFTransform(): not enough memory allocated to phase vector");
      return(OUT_SIZE_ERR);
    }
  if(x-&gt;n &gt; npts)
    gerror(FFT_TRUNC_WARN,"FFTransform(): signal length greater than FFT order (truncating)");

  /*
   * Copy signal to buffers and apply fft
   */
  for(i=0;in &amp;&amp; is[i];
  for(;i&lt; npts;i+=2,j++) {
    if(modul)
      modul-&gt;data[j]=(param_t)sqrt(tmp[i]*tmp[i]+tmp[i+1]*tmp[i+1]);
    if(phase)
      phase-&gt;data[j]=(param_t)atan(tmp[i+1]/tmp[i]);
  }
  if(modul)
    modul-&gt;n=npts/2;
  if(phase)
    phase-&gt;n=npts/2;
  DONE;
}

Code Display PlugIn

因為之前的 Code Display PlugIn 不好用
另外又找了一個 SyntaxHighlighter Evolved
試用看看如何
目前的 Code Display 設定 Default 為 Close 的
需要點 <> 這個標示才會顯示出 Code
與以前的 PlugIn 相比,比較不影響 Blog 的美觀度

超音波圖

小牛七週的超音波圖
dsc_2862

Mini2440 Leds Module Driver

終於開始寫 Mini2440 的 Module Driver
第一個學習的階段就是寫一個 Leds Module Driver
以下部分為 Driver Source

[sourcecode]
/*
** [2009.02.21][JUSTKU]
** hello.c - Demostrating the module_init() and module_exit() macros.
** This is prefered over using init_module() and cleanup_module()
*/

#include &lt;linux/init.h&gt;
#include &lt;linux/fs.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;asm/uaccess.h&gt;
#include &lt;asm/irq.h&gt;
#include &lt;asm/arch/regs-gpio.h&gt;

#define DRIVER_AUTHOR &quot;JUSTKU&quot;
#define DRIVER_DESC &quot;Mini2440 Led Char Driver&quot;
#define DEVICE_NAME &quot;MiniLeds&quot;
#define SUCCESS 0
#define NUM_LEDS 4
/*
** Prototypes
*/
static int __init leds_init(void);
static void __exit leds_exit(void);
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static int device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);

/*
** Global variables are declared as static, so are global within the file.
*/
static int Major; /* Major number assigned to our device driver */
static int Device_Open = 0 ;/* Is device open? */

static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.ioctl = device_ioctl,
.release = device_release,
};

static int _gLedStatus[NUM_LEDS]={0,0,0,0};
static unsigned long _gLedTable[] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};

static unsigned int _gLedCfgTable[]={
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};
/* Get rid of taint message by declareing code as GPL */
MODULE_LICENSE(&quot;Dual BSD/GPL&quot;);

static int __init leds_init(void)
{
int i;
Major = register_chrdev(0, DEVICE_NAME, &amp;fops);
if(Major &lt; 0)
{
printk(KERN_INFO &quot;Registering MiniLeds char device failed with %dn&quot;, Major);
return Major;
}
printk(KERN_INFO &quot;The process is &quot;%s&quot; (pid %i)n&quot;,current-&gt;comm, current-&gt;pid);
printk(KERN_INFO &quot;The driver major number is %dn&quot;, Major);
printk(KERN_INFO &quot;Create a dev file withn&quot;);
printk(KERN_INFO &quot;mknod /dev/%s c %d 0′.n&quot;, DEVICE_NAME, Major);
printk(KERN_INFO &quot;Try various minor numbers, Try to cat and echo to the device file&quot;);

devfs_mk_cdev(MKDEV(Major,0), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,DEVICE_NAME);

for( i = 0 ; i &lt; 4 ; i++ )
{
s3c2410_gpio_cfgpin(_gLedTable[i], _gLedCfgTable[i]);
s3c2410_gpio_setpin(_gLedTable[i], 1);
}
return SUCCESS;
}

static void __exit leds_exit(void)
{
/*
** Unregister the device
*/
int ret = unregister_chrdev(Major, DEVICE_NAME);
if(ret &lt; 0)
printk(KERN_INFO &quot;Error in unregister_chardev: %dn&quot;, ret);
devfs_remove(DEVICE_NAME);
}

/*
** Method Implement
*/

/*
** Called with a process tries to open the device file, like
** &quot;cat /dev/MiniLeds’
*/
static int device_open(struct inode *inode, struct file *file)
{
static int counter = 0;
if(Device_Open)
return -EBUSY;

Device_Open++;

try_module_get(THIS_MODULE);

return SUCCESS;
}

/*
** Called when a process closes the device file
*/
static int device_release(struct inode *unode, struct file *file)
{
Device_Open–;
/*
** Decrement the usage count, or else once you open the file,
** you’ll never get rid of the module
*/
module_put(THIS_MODULE);
return 0;
}
/*
** Called when a process, which already opened the dev file, attempts to
** read from it.
*/
static ssize_t device_read(struct file *filep, /* see include/linux/fs.h */
char *buff, /* buffer to fill with data */
size_t length, /* length of the buffer */
loff_t *offset)
{
/*
** Number of bytes actually read to the buffer
*/
int bytes_read = sizeof(_gLedStatus);
copy_to_user(buff, (char*)_gLedStatus, bytes_read);
return bytes_read;
}

/*
** Called when a proces, which already opened the dev file, attempts to
** write from it.
*/
static ssize_t device_write(struct file *filep, /* see include/linux/fs.h */
const char *buff, /* buffer to fill with data */
size_t length, /* length of the buffer */
loff_t *offset)
{
/*
** Number of bytes actually written to the buffer
*/
printk(KERN_ALERT &quot;Sorry, this operation isn’t supported.n&quot;);
return -EINVAL;
}

static int device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case 0:
case 1:
if(arg&gt;4)
{
return -EINVAL;
}
s3c2410_gpio_setpin(_gLedTable[arg],!cmd);
return 0;
default:
return -EINVAL;
}
}

module_init(leds_init);
module_exit(leds_exit);
/*
** Who wrote this module ?
** What does this module do ?
*/
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
/*
** This module uses /dev/MINIHELLO. The MODULE_SUPPORT_DEVICE macro might
** be used in the future to help automatic configuration of modules, but is
** currently unused other than for documentation purpose.
*/
MODULE_SUPPORTED_DEVICE(&quot;MINIHELLO&quot;);
[/sourcecode]

TEST CODE 的部分為

[sourcecode]
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/ioctl.h&gt;

int main(int argc, char **argv)
{
int fd;
int vLed;
int vVal;

fd = open(&quot;/dev/MiniLeds&quot;, 0);
if(fd&lt;0)
{
printf(&quot;Can not open devicen&quot;);
exit(1);
}

while(1)
{
printf(&quot;Please select led number(0~3) to run programn&quot;);
scanf(&quot;%d&quot;, &amp;vLed);
printf(&quot;Please set led %d On/Offn&quot;);
scanf(&quot;%d&quot;, &amp;vVal);
ioctl(fd, vVal, vLed);

if(vLed==4)
break;

}
close(fd);
return 0;
}
[/sourcecode]

記得要將 Leds-play 關掉阿!!
/etc/rc.d/init.d/leds stop
TestMiniLeds 記得要先 chmod +x TestMiniLeds

以下為 Log Recoed

[root@FriendlyARM /Mini2440]# ls
TestMiniLeds hello hello.ko miniLeds.ko
[root@FriendlyARM /Mini2440]# insmod miniLeds.ko
The process is “insmod” (pid 524)
The driver major number is 253
Create a dev file with
mknod /dev/MiniLeds c 253 0′.
Try various minor numbers, Try to cat and echo to the device file[root@FriendlyARM /Mini2440]#
[root@FriendlyARM /Mini2440]# ./TestMiniLeds
Please select led number(0~3) to run program
1
Please set led 1 On/Off
1
Please select led number(0~3) to run program
0
Please set led 0 On/Off
1
Please select led number(0~3) to run program
2
Please set led 2 On/Off
0
Please select led number(0~3) to run program

Mini2440 使用 arm-linux-gcc build char driver module

在之前的文章有提過如何在 Linux build 一個 hello 的 char driver
但這個如果 char driver module 要在 Mini2440 上使用
必須要以 arm-linux-gcc build 才可以
但卻又不是使用 arm-linux-gcc -o hello hello.c 就可以
經過 Google 的 search 後
寫了一個 Makefile 來完成 Build 的步驟

KERNELDIR=/usr/src/FriendlyARM/kernel-2.6.13
PWD := $(shell pwd)

CC =/usr/local/arm/3.4.1/bin/arm-linux-gcc

obj-m := hello.o

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core.depend .*.cmd *.ko *.mod.c .tmp_versions

重點是要設定 KERNEL 的 INCLUDE SOURCE
Build 成功後會產生一個 hello.ko
將 hello.ko 利用 zModem 傳到 Mini2440 上 (command line 打 rz 接收)
再 insmod hello.ko
可利用 lsmod 來查看

WinAvi FLV Converter

最近看到 Youtube 不錯的影片
研究了一下想要抓下 FLV 檔
1.
可以透過 Web 方式下載,這裡有 36 種不同的方法
http://blog.kusos.com/2007/10/72.html
2.
透過軟體
推薦可以使用 WinAVI FLV Converter 下載 FLV
並可以轉換成各種格式

使用 WinAVI 跟 IPOD 可說是絕配的組合阿

Mini2440 Hello char driver

hello.c
[sourcecode]
/*
** [2009.02.21][JUSTKU]
** hello.c - Demostrating the module_init() and module_exit() macros.
** This is prefered over using init_module() and cleanup_module()
*/

#include &lt;linux/init.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/sched.h&gt;

#define DRIVER_AUTHOR &quot;JUSTKU&quot;
#define DRIVER_DESC &quot;Mini2440 Hello Char Driver&quot;

/* Get rid of taint message by declareing code as GPL */
MODULE_LICENSE(&quot;Dual BSD/GPL&quot;);

static int __init hello_init(void)
{
printk(KERN_INFO &quot;Hello, worldn&quot;);
printk(KERN_INFO &quot;The process is &quot;%s&quot; (pid %i)n&quot;,current-&gt;comm, current-&gt;pid);
return 0;
}

static void __exit hello_exit(void)
{
printk(KERN_INFO &quot;Goodbye, cruel worldn&quot;);
}

module_init(hello_init);
module_exit(hello_exit);
/*
** Who wrote this module ?
** What does this module do ?
*/
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
/*
** This module uses /dev/MINIHELLO. The MODULE_SUPPORT_DEVICE macro might
** be used in the future to help automatic configuration of modules, but is
** currently unused other than for documentation purpose.
*/
MODULE_SUPPORTED_DEVICE(&quot;MINIHELLO&quot;);

[/sourcecode]

Makefile
[sourcecode]
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
[/sourcecode]

以下是 Log

kernel@kernel-desktop:~/driver-example$ make
make -C /lib/modules/2.6.24-19-generic/build M=/home/kernel/driver-example modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-19-generic’
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-19-generic’
kernel@kernel-desktop:~/driver-example$

kernel@kernel-desktop:~/driver-example$ modinfo hello.ko
filename: hello.ko
description: Mini2440 Hello Char Driver
author: JUSTKU
license: Dual BSD/GPL
srcversion: B2A9A23E4AAE15500DEBADE
depends:
vermagic: 2.6.24-19-generic SMP mod_unload 586
kernel@kernel-desktop:~/driver-example$ sudo insmod hello.ko

kernel@kernel-desktop:~/driver-example$ sudo rmmod hello
kernel@kernel-desktop:~/driver-example$ dmesg
[35554.786547] Hello, world
[35554.786561] The process is “insmod” (pid 7777)
[35639.186938] Goodbye, cruel world

以上可以在 UBuntu 上面順利運行

Mini2440 led-player

上篇我們寫了一個 Led 的測試程式
但發現在開機後,Led 就會自動在閃呀閃的!

研究了一下
發現是在 Linux 開機時會去啟動一個 Leds 的 Service
打開 /etc/inittab_

[root@FriendlyARM /etc]# ls
boa group inetd.conf_ mime.types pointercal resolv.conf
fstab host.conf init.d mtab profile services
ftpchroot hosts inittab_ passwd protocols sysconfig
ftpusers inetd.conf login.defs passwd_ rc.d
[root@FriendlyARM /etc]# vi inittab_

inittab_ 是開機會自動被執行的一個 sh
內容如下

#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg,
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#

# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#

# System initialization.
::sysinit:/etc/init.d/rcS
::askfirst:/sbin/getty 115200 console
~
~

我們可以看得出來當 System Initial 時會自動執行 /etc/init.d/rcS
打開 :/etc/init.d/rcS

/etc/rc.d/init.d/netd start
echo ” ” > /dev/vc/0
echo “Starting networking…” > /dev/vc/0
usleep 300000
/etc/rc.d/init.d/httpd start
echo ” ” > /dev/vc/0
echo “Starting web server…” > /dev/vc/0
usleep 300000
/etc/rc.d/init.d/leds start
echo ” ” > /dev/vc/0
echo “Starting leds service…” > /dev/vc/0
echo ” ”
usleep 300000

/sbin/ifconfig lo 127.0.0.1
/sbin/ifconfig eth0 192.168.1.230 up

/bin/qtopia &
echo ” ” > /dev/vc/0
echo “Starting Qtopia, please waiting…” > /dev/vc/0

/bin/hostname -F /etc/sysconfig/HOSTNAME

以下這行是啟動 leds 的 service

/etc/rc.d/init.d/leds start

再打開 /etc/rc.d/init.d/leds
[sourcecode]
#!/bin/sh
base=led-player

# See how we were called.
case 1; in start
/sbin/$base &amp;
;;
stop)
pid=`/bin/pidof $base`
if [ -n pid ]; then
kill -9 $pid
fi
;;
esac

exit 0
[/sourcecode]

以上看得出來當有參數 start 時會去執行 /sbin/led-player
stop 時會去執行 kill 的動作

[root@FriendlyARM vc]# /bin/pidof led-player
283

所以如果要啟動或是停止 service 的寫法可參考此部分

Page 1 of 212»