1. XawTV
If compilation succeed, then one can capture raw camera input data into file. Below is one example to save video.raw file during first 5 seconds.
./streamer -video /dev/video0 -t 0:5 -f 422 -s 640x480 -r 24 -o video.raw
 

2. One way to stream live webcam video using vlc

(Referred: http://superuser.com/questions/567016/live-streaming-using-ffmpeg)

Environment

OS: Ubuntu 13.1

Webcam : Microsoft Corp. LifeCam VX-1000

Web-server running on 192.168.1.20


Ok. now lets do the jobs to stream live webcam via vlc and webbrowser

First make sure vlc is installed.

sudo apt-get install vlc 

1
sudo apt-get install vlc

If you installed vlc, then you can execute cvlc. So run below command


1
cvlc v4l2:// :v4l2-vdev="/dev/video0" --sout '#transcode{vcodec=h264,vb=512,scale=1,acodec=none,venc=x264{aud,profile=high,level=60,keyint=15,bframes=0,ref=1,nocabac}}:duplicate{dst=std{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=/var/www/live/mystream.m3u8,index-url=http://192.168.1.20/live/mystream-########.ts},mux=ts{use-key-frames},dst=/var/www/live/mystream-########.ts},dst=std{access=http,mux=ts,dst=:8082/video.mp4}}' &


Note: The above command may fail if you don't have "/var/www/live/" folder created and have right permission to access it.

After successful running the above command without any error, then use can access this live stream from web page addressed http://<serve_ip_address>/live.

Posted by kevino
,

In the previous article, how to run OKL4 based application with android emulator was introduced. Here this time I will introduce another virtualization series, EmbeddedXen running on top of qemu. 

Before diving deep into this virtualization world, I knew there are only two XEN implementations on ARM architecture , one is XEN-ARM, don't know what exact name for this project, maintained by samsung and the other is EmbeddedXen. When I investigated two candidates to test, I could not find the source code for XEN-ARM but for EmbeddedXen, there is an official web site and source code is also available so I picked up Embedded Xen to test the feasibility and performance of virtualized embedded system.

Testing environment

Host OS: Windows XP or above
Cross compiler to compile EmbeddedXen for ARM: android NDK toolchain version arm-eabi-gcc-4.2.1
Compiler to compile qemu: latest MinGW gcc.

Building EmbeddedXen

There is already a good wiki page explaining to build and test but in Windows machine, some parts should be fixed and I will explain these below. It should be noted that this image, at default, can be built to be runnable on a virtual mainstone board which can be setup with qemu.

  • Download source codes: Open cygwin shell and install git if you don't have git installed using cygwin setup application. 
$ git clone git://embeddedxen.git.sourceforge.net/gitroot/embeddedxen/embeddedxen

$ cd embeddedxen
$ patch -p1 < ../embeddedxen-cygwin-patch.diff

  • Compile the sources:

$ build-embeddedxen -u -0 -x

This script will generate an u-boot compatible image which can be loaded in the virtual machine known as mainstone. This generated image is flashable and has no debugging information. If you want to debug Xen, then there is a symbolic image named as vmlinux.xen containing full debugging information. Later I will show how to debug xen code with help of gdb.


Building custom qemu executable

qemu-0.12.5 version can be compiled under MinGW shell so open MinGW shell. configure may require to install zlib and optional SDL library. In this case, here is a useful link
Original qemu source seems to have a bug which cannot start boot loader code when this embeddedXen rom is loaded so a patch file for this should be applied. Now let's do it.

  • Download source and untar it.

$ cd {work_directory}
$ wget http://download.savannah.gnu.org/releases/qemu/qemu-0.12.5.tar.gz
$ tar xvfz qemu-0.12.5.tar.gz

  • Download a patch file enable to load and run the above xen image and apply it.

$ patch -p0 < qemu-xen-mingw.diff

  • Compile qemu

$ cd qemu-0.12.5
$ configure --target-list=arm-softmmu --enable-sdl
$ make



Running EmbeddedXen

In order to simulate mainstone board on qemu, two flash files should be provided and here is the command to create them

$ cd {work_directory}
$ mkdir images
dd if=/dev/zero of=./images/flash1 bs=32M count=1
dd if=/dev/zero of=./images/flash2 bs=32M count=1

Now it is time to launch qemu with embeddedXen image

$ qemu-0.12.5/arm-softmmu/qemu-system-arm -localtime -M mainstone -kernel embeddedxen/xen/arch/arm/boot/uImage.mainstone -pflash ./images/flash1 -pflash ./images/flash2 -m 256 -serial telnet::4444,server



Debugging EmbeddedXen with gdb

As you can see in the above picture, there seems to be some bug in the xen code around mapping I/O of mainstone. You want to debug it? No problem, here is the instruction.

1. Add -s and -S option in the above command line. "-s" option make gdb enable remote debugging through TCP::1234 and "-S" option make qemu wait until gdb connection is established.

$ qemu-0.12.5/arm-softmmu/qemu-system-arm -localtime -M mainstone -kernel embeddedxen/xen/arch/arm/boot/uImage.mainstone -pflash ./images/flash1 -pflash ./images/flash2 -m 256 -serial telnet::4444,server -s -S

2. Open telnet session with address 127.0.0.1:4444 and connect.

3. After telnet connection for serial console is made, open another shell windows and run gdb and set break point.

$ cd {work_directory}
$ arm-eabi-gdb embeddedxen/vmlinux.xen
(gdb) br __start_xen_arm
(gdb) target remote :1234
(gdb) c


Then after few second, gdb will be waiting for user input at the break point.

(gdb) br __start_xen_arm
Breakpoint 1 at 0xff0089bc: file xen/arch/arm/hypervisor/setup.c, line 550.
(gdb) c
The program is not being run.
(gdb) target remote :1234
Remote debugging using :1234
[New Thread 1]
0xa0000000 in ?? ()
(gdb) c
Continuing.

Breakpoint 1, __start_xen_arm () at xen/arch/arm/hypervisor/setup.c:550
550             mbi.mods_count = 1;
(gdb)



free counters
Posted by kevino
,
이 글은 GTK를 사용하는 데 있어서 필요한 사항들에 대해 직접 사용해본 경험을 소개하는 글로 누구에게라도 도움이 되지 않을 까 해서 올려봅니다. 

gtk에서 별도의 쓰레드를 만들지 않고 간단하게 소켓통신 기능을 추가하려고 한다면 GIOChannel이 그 대안이 될 수 있다.

리눅스에서 GTK 프로그래밍 할때 대부분의 애플리케이션은 다음과 같은 초기화부분과 하나의 회돌이(loop)를 가진다

/* 주 윈도우 만들기 */
MainWindow = create_dialog1();
  gtk_widget_show (MainWindow);
/* 애플리케이션 종료 신호에 대한 콜백 설정하기 */
  g_signal_connect ((gpointer) MainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  g_signal_connect (MainWindow, "delete_event", gtk_main_quit, NULL); /* dirty */
/* 필요한 위젯 추가하기 */
  //GtkMsg_Init(MainWindow);
  /* MainWindow에 달린 모든 위젯 표시 */
  gtk_widget_show_all (MainWindow);
/* 종료신호가 콜백함수에서 처리될때 까지의 무한 회돌이 */
  gtk_main();

애플리케이션이 이러한 구조를 가질때 소켓통신 기능을 추가하려고 한다면 어떻게 해야 하는가?
일반적으로 소켓 통신을 하기 위해서는 별도의 쓰레드를 만들어서 사용하게 되는데 쓰레드의 관리가 싫은 경우 쓰레드의 생성없이 비슷한 효과를 낼 수 있도록 하기 위해 리눅스에서는 poll()함수를 이용한 GIOChannel을 지원한다.

다음은 GIOChannel의 사용예이다.


/* 소켓에서 읽을 데이터가 있을 경우 호출될 콜백 함수 */
static void client_signal_handler_threaded(GIOChannel *channel, GIOCondition condition, GtkEntry *entry )
{
gchar message[MAX_MSG_LEN];
gsize length;
g_io_channel_read_chars (channel, message, MAX_MSG_LEN, &length, NULL); printf("client_signal_handler_threaded: Received: %s",message);
}

int init_giochannle(int fd, tDTUN_PROCESS_HANDLER1 handler) 
{
        /* GIOChannel 생성 */
ctl_io = g_io_channel_unix_new(fd);
if ( ctl_io == NULL )
{
error("create_subprocess: error => failed to create a new GIOChannel.\n");
return -1;
}
g_io_channel_set_encoding ( ctl_io, NULL, NULL);
        /*  NONBLOCK 속성 설정 */
g_io_channel_set_flags( ctl_io, G_IO_FLAG_APPEND| G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_set_close_on_unref( ctl_io, TRUE);
        /* G_IO_IN 이벤트시 호출될 콜백함수 설정 */
result = g_io_add_watch( ctl_io, G_IO_IN, handler, NULL);
if ( !result )
{
error("create_subprocess: error => Cannot add watch on GIOChannel=%d.\n", ctl_io); perror("g_io_add_watch");
}
   }

main() {
..........

loop = g_main_loop_new (NULL, FALSE);
/* Setup for giochannel */
init_giochannle(sockfd, client_signal_handler_threaded);
g_main_loop_run (loop); /* Wheee! */
}


GIOChannel의 사용상 이점은 GTK나 gmain_loop_run()사용시 별도의 쓰레드를 사용하지 않고 비정기적으로 발생되는 이벤트에 대해서 처리가 가능하다는 점이다. 또 주 회돌이에서 빈번하게 타이머등을 사용하여 해당 이벤트를 검사하지 않고, 콜백함수를 호출하도록만 설정해놓음으로서 코드가 간결해 진다는 점에 있다.
  





free counters
Posted by kevino
,

SMTC(Symmetric Multi Thread Context)란 무엇인가

휴대형 단말기기에서 요구되는 멀티미디어 및 3D의 처리와 같은 시스템 성능이 커져 갈 수록 병렬 컴퓨팅의 필요가 점증하고 있다. 여기서는 그중에 하나의 시도를 보여주고 있는 SMTC에 대해 소개의 형식을 빌려 간단하게 얘기할까 합니다.

 

Symmetric Multi-thread Context의 의미를 알려면 먼저 multi thread multi processing의 차이점을 알아야 합니다. 이들에 차이는 인터넷에 잘 나와 있기 때문에 여기서는 좀 다른 시각으로 설명해볼까 합니다.

 

세상에 존재하는 어떠한 컴퓨터에서도 일관되게 적용될 수 있는 프로세스, 쓰레드 같은 단어의 엄밀한 정의는 사실 없다고 봐도 무방합니다. 하지만 여기서는 리눅스와 같이 시스템 내에 프로세스와 쓰레드가 같이 존재하는 시스템으로 국한해서 일반적으로 인식되는 각각의 특성을 확인해 보도록 하겠습니다.

 

프로세스: 넓은 의미에서의 하나의 일관된 작업. 리눅스에서 ls와 같이 프로그램을 실행하면 하나의 프로세스가 생성되게 되는데 이러한 하나의 프로세스는 일반적으로 다른 프로세스에 의해 침해 당하지 않는 메모리 영역을 가지는 특성이 있다. 즉 원칙적으로 하나의 프로세스의 코드가 자신과 다른 프로세스의 코드를 접근할 수 없도록 차단하여 시스템의 안정성을 확보할 수 있다.

 

프로세스에서의 context라 함은 프로세스를 시작과 끝이 있는 하나의 원기둥이라 가정할 때 가로로 원기둥을 자른 단면을 context라 합니다. 쉽게 얘기해서 멀티 프로세스 시스템에서 실행중인 프로세스는 다른 프로세스에게 제어권을 넘기고 휴면상태에 들어 갔다가 다시 제어권을 받아오면 예전과 동일한 상태로 돌아가야지 향후 프로그램이 의도했던 방향으로 흘러가게 되는데 원상복구에 필요한 모든 정보를 context라 얘기합니다. 이들 정보는 그림에 나와있는 것 이외에 추가적으로 필요하지만 이들을 모두 하드웨어에서 처리하는 것은 비용대비 효율성 측면에서 바람직하지 않기에 필요한 내용만을 하드웨어에서 처리하도록 되어 있습니다.

 

예를 들어 스택의 경우 프로세스간 보호를 위해 독자적인 영역을 가지고 있기 때문에 스택 전체가 context의 구성원이지만 프로세스 전환시 스택 전체를 백업하는 것이 아니라 stack pointer정보만 보관하고 있으면 프로세스 복구시 정확한 상태복원이 가능합니다. 또한 리눅스 시그널 관련 상태값도 프로세스의 정확한 복구에 필요한 사항이지만 이것을 하드웨어적으로 지원하지는 않고 소프트웨어적으로 지원하도록 하고 있습니다.

 

 

 

쓰레드:  쓰레드는 실행 루프 단위로 얘기할 수 있는데 프로그래머에 의해 선택된 작업 묶음이다. 하나의 프로세스가 한개의 쓰레드를 가질 수도 있지만 성능향상을 위해서 여러개의 쓰레드로 나누어 프로세스를 진행시킬수도 있다. 하나의 프로세스안에 여러개의 쓰레드를 가질 수 있는데 이런 시스템에 대해 MultiThread를 지원한다고 말하며, 쓰레드의 전환시에는 보다 적은 정보만을 저장했다가 이어진행시에 복원해서 사용하기 때문에 속도가 빠르다. 


Thread context로는 Register file들과 그외 Thread 복구에 필요한 정보들이 포함됩니다이들 정보로는 TLB 관련 내용도 넓은 의미에서 포함할 수 있지만 이는 CPU제조업체의 판단에 따라 하드웨어적으로 지원하기도 하고 소프트웨어로 처리할 것을 요구하기도 한다.

 

SMP SMTC의 차이점은

 

Symmetric Multi Processing은 동등한*(Symmetric) CPU가 여러 개 있어서 프로세스가 각각의 CPU에서 동작하는 것을 의미합니다. 각각의 CPU가 독자적으로 MMU, ALU, 각종 PIPE line 등을 가지고 있습니다. 그래서 2개의 cpu가 있고 2개의 프로세스가 돌아가는 시스템이 있다면 프로세스 전환시에 context switch가 필요없게 되니 그만큼 성능면에서 이득을 봅니다.

 


 

 

 

그러면 Symmetric* Multi-Thread Context는 무엇일까요? Thread context가 하나의 코어안에 여러벌을 보관할 수 있게 하드웨어가 지원하는 것을 의미하는 것으로, SMTC를 지원하는 시스템은 멀티쓰레드를 전환할때 소프트웨어로 처리해야 될 부분이 하드웨어에서 처리해준다는 점에서 성능향상을 보여줄 수 있습니다. 다른말로는 하드웨어 쓰레드를 지원하는 것으로 주로 Register Set들이 CPU내부에 여러 벌 준비되어 있는 경우를 의미합니다그 외 아래의 그림에서 나와 있다시피 interrupt mask와 같은 내용도 별도의 레지스터를 통해 보관할 수 있습니다.

 

여기에 나타난 그림을 보면 더욱 명료하게 보여지는데 단색의 주황색부분은 하드웨어의 실체가 존재하는 것을 의미하고 색이 섞인 블록은 한 개의 하드웨어를 시분할해서 사용하는 것으로 나타나 있음을 볼 수 있습니다.

 

 

SMTC의 지원을 위해서는 CPU가 이 기능을 지원해야 할 것이고 거기에 따른 사용방법도 제조업체에서 지원해야 합니다. 위의 그림의 출처는 다음을 참고. http://elinux.org/upload/7/7b/CELF_SMTC_April_2006_v0.3.pdf

 

자 그러면 왜 SMP가 나온 후 SMTC 시스템이 나왔을까요? 간단합니다. SMP는 복수개의 하드웨어를 장착해야 하므로 성능이 좋은 반면 CPU의 설계가 복잡해지고 다이크기가 커지고 파워를 많이 잡아먹는 여러가지 약점이 있는 반면, SMTC 시스템은 어느 정도 multi thread의 하드웨어적인 지원을 통해 성능향상 대비 제조단가 및 전원 소모량의 trade off를 고려하여 내놓은 절충선이라 할 수 있습니다. 향후 모바일 장비에서도 성능향상의 요구에 따라 병렬 프로세싱의 요구가 커질텐데 비용과 전력요구량 면에서 이점을 보이는 SMTC 기능을 지원하는 CPU가 대안이 될 수 있을지 기대됩니다.



추가 참고 자료:

1.     http://www.ddj.com/hpc-high-performance-computing/194500234;jsessionid=ZFTD05R2STNC5QE1GHRSKH4ATMY32JVN?_requestid=107789


2.     http://elinux.org/upload/7/7b/CELF_SMTC_April_2006_v0.3.pdf


3.   리눅스에서의 thread 관련 자료: http://www.ibm.com/developerworks/kr/library/l-threading.html






free counters
Posted by kevino
,
How to debug linux application on beagle board using single com port 
------------------------------------------------------------- 

1. Install the compiler for arm linux 
===================================== 
ARM Linux GCC - codesourcery tool chain (Select GNU/Linux and download 
version 2007q3) 
download from: http://www.codesourcery.com/gnu_toolchains/arm/portal/release313 
297209683 Aug 11 11:08 arm-2007q3.tar.bz2 
and install 
so you could compile using the arm compiler using the command line: 
"arm-none-linux-gnueabi-gcc" 
(complete info at: http://code.google.com/p/beagleboard/wiki/BeagleSoftCompile

2. u-boot 
========= 

You need u-boot to be automated, for that recompile the u-boot after 
doing the following changes in 
the file ./include/configs/omap3530beagle.h 

        #define CONFIG_BOOTCOMMAND "mmcinit;fatload mmc 0 0x80300000 
uImage;fatload mmc 0 0x81600000 rd-ext2.bin;bootm 0x80300000;\0" 

        #define CONFIG_BOOTARGS "setenv bootargs console=ttyS1,115200n8 
ramdisk_size=8192 root=/dev/ram0 rw rootfstype=ext2 
initrd=0x81600000,8M nohz=off" 

and from /board/omap3530beagle/omap3530beagle.c 
comment the following two lines at the end of the function 
misc_init_r() 
        //      dss_init(); 
        //      audio_init(); 

Compile the u-boot to generate the u-boot.bin file 
        make CROSS_COMPILE=arm-none-linux-gnueabi- distclean 
        make CROSS_COMPILE=arm-none-linux-gnueabi- omap3530beagle_config 
        make CROSS_COMPILE=arm-none-linux-gnueabi- 

more info at: 
http://code.google.com/p/beagleboard/wiki/BeagleSoftCompile 

3. MLO 
====== 
MMC is the first step of the MMC based bootloader 
I did not bother to compile it, just downloaded it from: 
http://code.google.com/p/beagleboard/wiki/BeagleSourceCode (and rename 
MLO_revb to MLO) 

4. Kernel 
========= 
Download kernel from same place as above: Linux Kernel 2.6.22.18 
and compile it using: 
        make CROSS_COMPILE=arm-none-linux-gnueabi- distclean 
        make CROSS_COMPILE=arm-none-linux-gnueabi- omap3_beagle_defconfig 
        make CROSS_COMPILE=arm-none-linux-gnueabi- uImage 
or just use the compiled one from: 
http://code.google.com/p/beagleboard/wiki/BeagleSourceCode  (don't 
forget to rename it, if needed, to: uImage) 

5. The RAM files system (busybox) 
================================= 

download BusyBox (ramdisk) File System from the same place as above. 
filename: rd-ext2-8M.bin and rename it to rd-ext2.bin 

Changing the ramdisk to have it autostart the gdbserver: 
        cat rd-ext2-8M.bin | gunzip > myimagem 
        mkdir /mnt/tmp 
        mount myimage /mnt/tmp -t ext2 -o loop=/dev/loop3 

Now the full image is under /mnt/tmp, do the following changes there: 
change inside /mnt/tmp/etc/inittab 
from: 
        ::askfirst:-/bin/sh 
to: 
        ::respawn:-/bin/sh 
this is to avoid asking for the prompt "press..." on boot 

and at the end of the file /mnt/tmp/etc/profile add: 
        mount -t vfat /dev/mmcblk0p1 /mnt/mmc/ 
        cd /mnt/mmc 
        ./ycomarm /dev/ttyS2 
        ./gdbserver /dev/ttyS2 hello2 
This is to mount the mmc, and run gdbserver and have it ready to debug 
the hello2.c program 

Now pack the image back, and create a new rd-ext2.bin file 
        umount myimage  (before doing that, do cd to a different location) 
        cp myimage qqq 
        gzip qqq 
        rm rd-ext2.bin 
        mv qqq.gz rd-ext2.bin 

6. compiling the gdbserver and gdb for arm 
========================================== 

download the latest gdb-6.7.1.tar 
wget -c ftp://ftp.gnu.org/gnu/gdb/gdb-6.7.1.tar.bz2 

Place the downloaded file in /usr/src directory of your system. 
Under /usr/src, create a debug directory and extract the gdb package 
in this 
(/usr/src/debug) directory. 

[root at localhost]# cd /usr/src/debug 
[root at localhost]# tar jxf ../gdb-6.7.1.tar.bz2 

Build gdb debugger 

The debugger must be built into directories separate from the source. 
Thus, 
create a directory for gdb within the /usr/src/debug directory. 

[root at localhost]# mkdir /usr/src/debug/build_gdb 

Chose the prefix for the new debugger. This is a directory where the 
binary 
and other debugger files resides. This application report uses /opt/ 
gdebug 
for the new debugger. The directory is created by the installation of 
the 
tools. Go to the /usr/src/debug/gdb-6.3 directory to configure and 
then 
build the binary and other debugger files with the commands shown 
below. 

[root at localhost]# cd /usr/src/debug/build_gdb 
[root at localhost]# ../gdb-6.7.1/configure --target=arm-linux -- 
prefix=/opt/gdebug 
[root at localhost]# make 
[root at localhost]# make install 

The binary generated resides in /opt/gdebug and is fairly large. This 
is why 
the gdb binary can't be used as-is on the target and the gdbserver is 
used 
instead. 

Build gdb server 

The gdb server wasn't built earlier because it has to be cross- 
compiled for 
the target using the appropriate tools. To do so, create a directory 
to 
build the gdb server, move to it and build the gdb server: 

[root at localhost]# mkdir /usr/src/debug/build_gdbserver 
[root at localhost]# cd /usr/src/debug/build_gdbserver 
[root at localhost]# CC=arm-none-linux-gnueabi-gcc ../gdb-6.7.1/gdb/ 
gdbserver/configure 
--host=arm-linux --prefix=/opt/gdebug/arm-linux 
[root at localhost]# make 
[root at localhost]# make install 

The gdb server binary, 'gdbserver', has now been installed in your 
/opt/gdebug/arm-linux/bin directory. 

Once built, copy gdbserver to the MMC 

7. utility to setup the serial port 
=================================== 
compile ycom.c for both ARM and your PC using: 
arm-none-linux-gnueabi-gcc -o ycomarm ycom.c 
gcc -o ycom ycom.c 

This utility is used to setup the proper serial configuration BEFORE 
running gdb or gdbserver, and you can download it from: 
http://www.magniel.com/yuli/ycom.c 

8. Compiling the demo program hello2.c 
===================================== 
arm-none-linux-gnueabi-gcc -o hello2 hello2.c 
You can download it from: http://www.magniel.com/yuli/hello2.c 

9. Booting from MMC 
=================== 
Format MMC to FAT32 (use: HP MMC/SD Disk Format Tool) SP27213.exe 
Copy the following files to the MMC: 
MLO 
u-boot.bin   (the one that you modified) 
uImage 
rd-ext2.bin  (the one that you modified) 
ycomarm 
hello2.c 
hello2 
gdbserver 

Connect NULL modem cable to a PC, run hyperterminal: 115200,N,8,1 
Turn power to beagle, while pressing the 'USER' button 
It should run u-boot, and then execute the kernel, and at the end it 
should write: "TEST To send123" 

Connect the cable to a linux machine, login as root. 
Initialize the serial port for the proper speed, then envoke the gdb: 
        ./ycom /dev/ttyUSB1 
        /opt/gdebug/bin/arm-linux-gdbtui helloa 
and inside the gdb write: 
        target remote /dev/ttyUSB1 

you might use different serial port connection, so instead of ttyUSB1, 
the serial for your computer might be ttyS0 or similar. 
You can use the command "dmesg | grep tty" to display all available 
installed serial ports. 

10. Using the visual debugger ddd 
================================= 

download it, compile it, and use the following command line when 
running it: 
        ddd --debugger "/opt/gdebug/bin/arm-linux-gdb" 

Now power up beagle, wait a little (to ensure that the boot finished, 
and that gdbserver started to run), and then on the linux side start 
the debugger: 
        ./ycom /dev/ttyUSB1 
        ddd --debugger "/opt/gdebug/bin/arm-linux-gdb" 
and inside the gdb write: 
        target remote /dev/ttyUSB1 
        file hello2 

The file hello2 should be copied into the mmc. 

Yuli 
yk (at) magniel (dot) com 


Posted by kevino
,
Posted by kevino
,

Broadcasting video with Android - without writing to local files

in 

One of the weaker points of the Android platform is the Media API. When compared to the J2ME API, one important feature is missing: the ability to record to a stream and to playback from a stream.

Why is this important? There are a number of use cases.

For recording:

  • post-processing audio / video data before writing out to the file system
  • broadcasting audio / video without writing out the data first into the file system, which also limits the broadcast to the available free space on the device.

For playback:

  • pre-processing the audio / video data before playing
  • streaming using protocols that are not supported by the built-in media player

In this blog entry we will show a method to broadcast video (and audio) from an Android phone to a network server, without writing to the file system.

There is one promising method in the MediaRecorder class setOutputFile(FileDescriptor).

We know that in Linux also network sockets have file descriptors. But how could we access the file descriptor of a regular java.net.Socket?

Luckily, ParcelFileDescriptor comes to the rescue, where we can use the fromSocket(Socket) static method to create a ParcelFileDescriptor instance from a Socket object. From this instance, we may now grab the badly needed FileDescriptor.

It all boils down to these few lines (in pseudocode):

String hostname = "your.host.name";
int port = 1234;

Socket socket = new Socket(InetAddress.getByName(hostname), port);

ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);

MediaRecorder recorder = new MediaRecorder();

// Additional MediaRecorder setup (output format ... etc.) omitted

recorder.setOutputFile(pfd.getFileDescriptor());

recorder.prepare();

recorder.start();

Using this concept we created a small proof of concept application (together with an even simpler server), which is able to broadcast videos not limited in length by the available space on the SD Card.

There are a few gotchas, if you want to try this out yourself:

  • The MediaRecorder records either in 3GPP or in MP4 format. This file format consists of atoms, where each atom starts with its size. There are different kinds of atoms in a file, mdat atoms store the actual raw frames of the encoded video and audio. In the Cupcake version Android starts writing out an mdat atom with the encoded frames, but it has to leave the size of the atom empty for obvious reasons. When writing to a seekable file descriptor, it can simply fill in the blanks after the recording, but of course socket file descriptors are not seekable. So the received stream will have to be fixed up after the recording is finished, or the raw video / audio frames have to be processed by the server.
  • For some reason, the MediaRecorder also leaves the header of the file blank, which also has to be handled on the server.
  • High latency connections will cause the video to be choppy. Obviously some buffering is necessary. One method is to use a local mini server on the phone which receives the stream, buffers it, and sends to the remote server as fast as the network allows it. However, if using native code is an option, we can simply create a pipe to receive the data from the MediaRecorder. We will show this method in a future blog entry.

Trackback URL for this post:

http://www.mattakis.com/trackback/30
Posted by kevino
,
오랜만에 이솝싸이트를 찾아왔는데요 다름이 아니라 커널 선점형과 비선점형에 관해 질문이 있는데 정확한 답을 얻을 수 있는곳은 ...
이곳이라는 생각이 들더라구요. ^^

뭔가를 구현하려는것은 아니구요 그냥 단순 호기심때문에 질문드립니다.

제가 이해하기로는 비선점형은 커널 2.4에서
while(1){};
이라는 프로그램을 돌리면 비선점형 커널임이도 불구하고 다른 프로세스가 실행이 됩니다.
왜냐하면 process가 실행 될때 quantum (timeslice라고도 하는..) 타임이 할당되는데 이것이 끝나면 다른 프로세스가 실행되기때문입니다.
제가 생각하기론 커널 비선점이라고 하는 말은 "quantum 시간이 끝나기전엔 프로세스가 CPU를 안놓는다" 라고 이해하고 있습니다.

그런데 아주 priority가 높은 HW interrupt가 발생을 했다면 수행이 될것이냐가 논쟁의 핵심이었습니다.
수행이 된다고말한측에서 제시한 이유는 IDT 테이블를 통해 Soft IRQ에 인터럽트 핸들러가 수행이 될텐데.. 이 Soft IRQ handler 같은것은 커널이 따로 관리하는 다른 프로세스에 의해 수행되기때문에 즉시 수행된다는 것입니다.
그런거같기도 하고.... 아닌것같기도 하고... 헷갈리면서도 너무 궁금하네요.


답변:

선점형 커널에 대해서는 구글링하면 잘 나와있을텐데 그냥 아는 내용만 조금 적어보겠습니다.

비선점형과 선점형 커널의 차이는 race condition이나 무한 루프로 들어갔을때 시스템을 재부팅하지 않고 운영체제(더 정확히는 scheduler)에 의해 오류정정이 가능하냐에 따라 나뉘어 집니다. 일반적으로 커널 자체는 충분히 시험된 코드로 이루어져 race condition이나 무한 루프가 발생하는 경우가 없으나 문제는 디바이스 드라이버 코드에서 발생할 수 있습니다. 디바이스 드라이버의 코드(HW interrupt handler 포함)도 일반적으로 커널모드에서 동작하게 되는데 아무래도 커널자체보다는 검증되지 않은 코드로 이루어져 있고 여기서 시스템을 멈추는 상황이 발생할 수 있을텐데 진정한 선점형 커널은 이러한 문제도 문제점을 포착하고 해당 문제의 코드를 더이상 방해하지 못하도록 삭제할 수 있어야 합니다. 

중요한 내용은 멀티태스킹이 사용자가 잘 만들지 또는 도와주지 않으면 죽어버리는 협업형 멀티태스킹 환경과는 달리 사용자가(여기서는 주로 디바이스 드라이버 작성자) 도와주지 않더라도 최소한 시스템이 멈추지 않아야 한다는 겁니다. 이런 안정한 시스템을 만들기 위해서는 일반적인 커널 모드에서 동작하는 thread뿐만 아니라 HW interrupt handler도 스케줄러에서 주도권을 갖고 제어를 할 수 있어야 합니다.

참고로 High priority HW interrupt handler가 실행될지 않될지는 운영체제 마다 다릅니다. HW interrupt가 최초 인지되서 소프트웨어적으로 최종 실행되기까지 HW interrupt 인지 과정과 소프트웨어 인지과정을 순서대로 거치게 되는데 중간 단계마다 진행할지 말지 소프트웨어로 설정할 수 있어서 운영체제 작성자의 의도에 따라 최종 실행완료까지 될지가 달라지게 됩니다. 

질문의 "실행"이라는 단어가 의미하는 바가 애매해서 이거다라고 답변하기가 힘든데 일반적으로 인터럽트 핸들러까지는 실행된다라고 봅니다. 정말로 실행이 될지 안될지는 로그를 출력하게 해서 확인해봐야겠죠. 리눅스의 경우 태생이 비선점형 커널로 구조적인 문제로 아무리 real time patch 또는 preemptible patch를 적용시켰더라도 100% fault tolerant system을 보장하지는 않습니다. 정리하면 HW interrupt의 처리 여부는 운영체제의 특성에 따라 달라질 수 있다이고 일반적으로는 실행된다라고 봅니다.


Posted by kevino
,
데스크탑 환경: 리눅스 Ubuntu

문제 1: Ubuntu에서 user policy에 의해 wireshark같은 root 권한을 요청하는 애플리케이션이 실행되지 않을때 대응하는 방법

해결: System -> Administration -> users and groups

Account 'user name' Properties -> User previleges에서
Administer the system 항목을 check하면 된다.

문제 2: wireshark 같이 root권한을 필요로 하고 x-window를 사용하는 애플리케이션을 실행할 때 다음과 같은 메시지를 보이면서 동작되지 않는 상황에 대한 해결책 한가지

해결1: 사용자 ID를 sudo 목록에 등록시키고 난위 sudo ./wireshark를 실행할 것
1) visudo 실행
2) root 항목 바로 아래 사용자 ID 추가하고 root와 같은 설정 값으로 설정함


파일에서 특정 문자열 찾는 방법

1. 특정 확장자를 가진 파일에서의 특정 문자열을 찾는 방법
1.1 find . -type f -name "*.java" -exec grep -H "Zoom" {} \;

1.2 find . -type f -name *.mk -print | xargs grep -i "libhgl"

* 맥에서는 파일이름에 공백이 들어가 있는 경우 제대로 찾지 못하는 문제가 있다. 이럴때는 다음과 같이 명령을 주면 동작한다.

find . -iname "*.js" -print0 | xargs -I{} -0 grep -inH OnCollisionEnter "{}"

2. 현재 폴더에서 모든 text파일을 상대로 특정 문자열을 가진 파일목록 얻기
2.1 find . -type f -name "*" -print | xargs grep -il "libhgl"




Posted by kevino
,
개인적으로 발표할 기회가 있어서 만들어 놓은 프리젠테이션 장표입니다.

Posted by kevino
,