0
Metasepi team meeting #6:
 "Snatch-driven development"
"Snatch-driven
Kiwamu Okabe
Who am I?
☆ http://www.masterq.net/
☆ Twitter: @master_q
☆ Organizer of Metasepi project
☆ A developer of Ajhc Haskell com...
Agenda
☆ [1] Demo
☆ [2] What is Ajhc?
☆ [3] What is Metasepi?
☆ [4] What is compiler to build OS
☆ [5] How to use Ajhc
☆ [...
[1] Demo
☆ RSS reader running on mbed (ARM).
☆ Show reddit articles on LCD display.
☆ You can watch the movie following.
h...
Demo hardware
Architecture: ARM Cortex-M3
RAM size: 64kB
IO: Ethernet, LED, LCD, SD Card, USB
host/device, Serial
Demo software
github.com/ajhc/demo-cortex-m3
Demo source code
demo-cortex-m3
`-- mbed-nxp-lpc1768
|-- BuildShell
|-- build
|
`-- mbed.ld
|-- external
|
`-- mbed
|
`-- ...
[2] What is Ajhc?
http://ajhc.metasepi.org/
☆ Ajhc := A fork of jhc
☆ jhc := John's Haskell Compiler
☆ http://repetae.net/...
Why need Ajhc?
☆ GHC is de facto standard on Haskell.
☆ GHC := Glasgow Haskell Compiler
☆ http://www.haskell.org/ghc/
☆ Wh...
[3] What is Metasepi?
http://metasepi.org/
☆ Unix-like OS designed by strong type.
☆ Using ML or more strong type lang.
Ha...
Why need Metasepi?
☆ We have already Linux or Windows.
☆ But the developers are suffering.
☆ If use the kernel changed by ...
Doesn't OSS have good quality?
☆ "The Cathedral and the Bazaar"
☆ "Given enough eyeballs, all bugs are
shallow."
http://cr...
Low quality out of OSS umbrella
Type safety
☆ Less runtime errors.
☆ "数理科学的バグ撲滅方法論のすすめ"
http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/
Kernel desperately wants type
☆ Kernels are developed with C lang.
☆ Error on user space => SEGV
☆ Error on kernel space =...
[4] What is compiler to build OS
☆ Need strong type.
☆ Need flexibility such as C language.
☆ Create it if there are not!
...
Want POSIX free compiler
Programs to print "hoge" on terminal.

Measurement value is smaller,
dependence on POSIX is small...
Jhc output has only 20 undef
$ nm hs.out | grep
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U

"U "
_IO_putc@@GLIBC_2.2.5
__libc...
Jhc is translator to C language
Easy to cross build
Survive burning out
Let's develop in dogfooding style. (The
method is called "Snatch".)
[5] How to use Ajhc
Case of Ubuntu 12.04 amd64.
$ sudo apt-get install haskell-platform libncurses5-dev gcc m4
$ cabal upd...
Detail of usage
Please read "Ajhc User's Manual".
☆ ajhc.metasepi.org/manual.html
Also you can read in Japanese.
☆ ajhc.me...
[6] Case study: Snatch Android
Let's snatch sample app "native-activity".
developer.android.com/tools/sdk/ndk/
Snatch plan
[7] Detail of Snatch method
Let's watch Snatch animation on
Android NDK Apps. Have popcorn?
If you want to know more detai...
Step0: Before Snatch
// ### native-activity/jni/main.c ###
struct saved_state {
// --snip-struct engine {
// --snip-static...
Step1: Call Haskell empty code
-- ### native-activity/hs_src/Main.hs ###
main :: IO ()
main = return ()
// ### native-acti...
Step2: struct => Storable (cont.)
-- ### native-activity/hs_src/AndroidNdk.hs ###
{-# LANGUAGE ForeignFunctionInterface #-...
Step2: struct => Storable
instance Storable SavedState where
sizeOf
= const sizeOf_SavedState
alignment = sizeOf
poke p ss...
Step3: Snatch 1st func (cont.)
-- ### native-activity/hs_src/AndroidNdk.hs ###
newtype {-# CTYPE "AInputEvent" #-} AInputE...
Step3: Snatch 1st func
// ### native-activity/jni/main.c ###
extern int32_t engineHandleInput(struct engine* engine,
AInpu...
Step4: Snatch 2nd func (cont.)
-- ### native-activity/hs_src/AndroidNdk.hs ###
foreign import primitive "const.APP_CMD_SAV...
Step4: Snatch 2nd func
// ### native-activity/jni/c_extern.h ###
int engine_init_display(struct engine* engine);
void engi...
Step5: Snatch remaining funcs
Snatch the following functions.
☆ engine_init_display()
☆ engine_draw_frame()
☆ engine_term_...
Step6: Snatch main func (cont.)
-- ### native-activity/hs_src/Main.hs ###
main :: IO () -- Dummy
main = return ()
foreign ...
Step6: Snatch main func
// ### native-activity/jni/main.c ###
void android_main(struct android_app*
app_dummy(); // Make s...
Step7: Get clear => GOAL
We are in the strong typed world.
Haskell's turn, now!
PR: Call For Articles
☆ http://www.paraiso-lang.org/ikmsm/
☆ Fanzine of functional programming.
☆ About Haskell or OCaml o...
Upcoming SlideShare
Loading in...5
×

Metasepi team meeting #6: "Snatch-driven development"

2,707

Published on

Metasepi team meeting #6: "Snatch-driven development"

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,707
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
12
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Metasepi team meeting #6: "Snatch-driven development""

  1. 1. Metasepi team meeting #6:  "Snatch-driven development" "Snatch-driven Kiwamu Okabe
  2. 2. Who am I? ☆ http://www.masterq.net/ ☆ Twitter: @master_q ☆ Organizer of Metasepi project ☆ A developer of Ajhc Haskell compiler ☆ A Debian Maintainer ☆ 10 years' experience in developing OS using NetBSD.
  3. 3. Agenda ☆ [1] Demo ☆ [2] What is Ajhc? ☆ [3] What is Metasepi? ☆ [4] What is compiler to build OS ☆ [5] How to use Ajhc ☆ [6] Case study: Snatch Android ☆ [7] Detail of Snatch process
  4. 4. [1] Demo ☆ RSS reader running on mbed (ARM). ☆ Show reddit articles on LCD display. ☆ You can watch the movie following. http://bit.ly/mbedmov
  5. 5. Demo hardware Architecture: ARM Cortex-M3 RAM size: 64kB IO: Ethernet, LED, LCD, SD Card, USB host/device, Serial
  6. 6. Demo software github.com/ajhc/demo-cortex-m3
  7. 7. Demo source code demo-cortex-m3 `-- mbed-nxp-lpc1768 |-- BuildShell |-- build | `-- mbed.ld |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface | |-- c_extern.h | |-- dummy4jhc.c | |-- hs_src | | `-- *.hs | |-- main.c | `-- mbed-rtos `-- src `-- gcc4mbed.c <= Compile enviroment <= Linker Sscript <= mbed library (compiled) <= TCP/IP protocol stack <= C lanuage stub for Haskell <= <= <= Haskell source code C language main function mbed-rtos OS
  8. 8. [2] What is Ajhc? http://ajhc.metasepi.org/ ☆ Ajhc := A fork of jhc ☆ jhc := John's Haskell Compiler ☆ http://repetae.net/computer/jhc/ ☆ Jhc outputs binary that has lowmemory-footprint and runs fast. ☆ Good for embedded software.
  9. 9. Why need Ajhc? ☆ GHC is de facto standard on Haskell. ☆ GHC := Glasgow Haskell Compiler ☆ http://www.haskell.org/ghc/ ☆ Why need another Haskell compiler? ☆ To develop kernel named "Metasepi".
  10. 10. [3] What is Metasepi? http://metasepi.org/ ☆ Unix-like OS designed by strong type. ☆ Using ML or more strong type lang. Haskell http://www.haskell.org/ OCaml http://caml.inria.fr/ MLton http://mlton.org/ . . . and suchlike.
  11. 11. Why need Metasepi? ☆ We have already Linux or Windows. ☆ But the developers are suffering. ☆ If use the kernel changed by you, ☆ you will get many runtime error. ☆ Difficult even to reproduce it.
  12. 12. Doesn't OSS have good quality? ☆ "The Cathedral and the Bazaar" ☆ "Given enough eyeballs, all bugs are shallow." http://cruel.org/freeware/cathedral.html ☆ But if you develop your own product reusing OSS...
  13. 13. Low quality out of OSS umbrella
  14. 14. Type safety ☆ Less runtime errors. ☆ "数理科学的バグ撲滅方法論のすすめ" http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/
  15. 15. Kernel desperately wants type ☆ Kernels are developed with C lang. ☆ Error on user space => SEGV ☆ Error on kernel space => halt! ☆ Should design kernel with the greatest care. ☆ C language is safe?
  16. 16. [4] What is compiler to build OS ☆ Need strong type. ☆ Need flexibility such as C language. ☆ Create it if there are not! ☆ From scratch? No thank you... ☆ Look for our compiler base.
  17. 17. Want POSIX free compiler Programs to print "hoge" on terminal. Measurement value is smaller, dependence on POSIX is small.
  18. 18. Jhc output has only 20 undef $ nm hs.out | grep U U U U U U U U U U U U U U U U U U U U "U " _IO_putc@@GLIBC_2.2.5 __libc_start_main@@GLIBC_2.2.5 _setjmp@@GLIBC_2.2.5 abort@@GLIBC_2.2.5 ctime@@GLIBC_2.2.5 exit@@GLIBC_2.2.5 fflush@@GLIBC_2.2.5 fprintf@@GLIBC_2.2.5 fputc@@GLIBC_2.2.5 fputs@@GLIBC_2.2.5 free@@GLIBC_2.2.5 fwrite@@GLIBC_2.2.5 getenv@@GLIBC_2.2.5 malloc@@GLIBC_2.2.5 memset@@GLIBC_2.2.5 posix_memalign@@GLIBC_2.2.5 realloc@@GLIBC_2.2.5 setlocale@@GLIBC_2.2.5 sysconf@@GLIBC_2.2.5 times@@GLIBC_2.2.5
  19. 19. Jhc is translator to C language
  20. 20. Easy to cross build
  21. 21. Survive burning out Let's develop in dogfooding style. (The method is called "Snatch".)
  22. 22. [5] How to use Ajhc Case of Ubuntu 12.04 amd64. $ sudo apt-get install haskell-platform libncurses5-dev gcc m4 $ cabal update $ export PATH=$HOME/.cabal/bin/:$PATH $ cabal install ajhc $ which ajhc /home/USER/.cabal/bin/ajhc $ echo 'main = print "hoge"' > Hoge.hs $ ajhc Hoge.hs $ ./hs.out "hoge" You can use on Windows or Mac OS X.
  23. 23. Detail of usage Please read "Ajhc User's Manual". ☆ ajhc.metasepi.org/manual.html Also you can read in Japanese. ☆ ajhc.metasepi.org/manual_ja.html
  24. 24. [6] Case study: Snatch Android Let's snatch sample app "native-activity". developer.android.com/tools/sdk/ndk/
  25. 25. Snatch plan
  26. 26. [7] Detail of Snatch method Let's watch Snatch animation on Android NDK Apps. Have popcorn? If you want to know more detail, try the following. $ $ $ git clone https://github.com/ajhc/demo-android-ndk.git cd demo-android-ndk git log -p
  27. 27. Step0: Before Snatch // ### native-activity/jni/main.c ### struct saved_state { // --snip-struct engine { // --snip-static int engine_init_display(struct engine* engine) { // --snip-static void engine_draw_frame(struct engine* engine) { // --snip-static void engine_term_display(struct engine* engine) { // --snip-static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { // --snip-static void engine_handle_cmd(struct android_app* app, int32_t cmd) { // --snip-void android_main(struct android_app* state) { // --snip--
  28. 28. Step1: Call Haskell empty code -- ### native-activity/hs_src/Main.hs ### main :: IO () main = return () // ### native-activity/jni/main.c ### void android_main(struct android_app* state) { // --snip-{ // Run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv; hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); } // --snip--
  29. 29. Step2: struct => Storable (cont.) -- ### native-activity/hs_src/AndroidNdk.hs ### {-# LANGUAGE ForeignFunctionInterface #-} module AndroidNdk where import Foreign.Storable import Foreign.C.Types import Foreign.Ptr foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Int foreign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Int foreign import primitive "const.offsetof(struct saved_state, offsetOf_SavedState_x :: Int foreign import primitive "const.offsetof(struct saved_state, offsetOf_SavedState_y :: Int data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int } x)" y)"
  30. 30. Step2: struct => Storable instance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y } -- snip -- // ### native-activity/jni/c_extern.h ### struct saved_state { float angle; int32_t x; int32_t y; };
  31. 31. Step3: Snatch 1st func (cont.) -- ### native-activity/hs_src/AndroidNdk.hs ### newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent () foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Int foreign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Int foreign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Float foreign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO Int engineHandleInput eng event = do t <- c_AInputEvent_getType event if t /= c_AINPUT_EVENT_TYPE_MOTION then return 0 else do enghs <- peek eng let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0 let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs' return 1
  32. 32. Step3: Snatch 1st func // ### native-activity/jni/main.c ### extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; return engineHandleInput(engine, event); }
  33. 33. Step4: Snatch 2nd func (cont.) -- ### native-activity/hs_src/AndroidNdk.hs ### foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int -- snip -foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Int foreign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO () -- snip -foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int engineHandleCmd :: Ptr AndroidEngine engineHandleCmd eng cmd | cmd == c_APP_CMD_SAVE_STATE = do -- snip -- -> Int -> IO () enghs <- peek eng let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs
  34. 34. Step4: Snatch 2nd func // ### native-activity/jni/c_extern.h ### int engine_init_display(struct engine* engine); void engine_draw_frame(struct engine* engine); void engine_term_display(struct engine* engine); // ### native-activity/jni/main.c ### extern void engineHandleCmd(struct engine* engine, int32_t cmd); static void engine_handle_cmd(struct cmd) { struct engine* engine = (struct engineHandleCmd(engine, cmd); } android_app* app, int32_t engine*)app->userData;
  35. 35. Step5: Snatch remaining funcs Snatch the following functions. ☆ engine_init_display() ☆ engine_draw_frame() ☆ engine_term_display()
  36. 36. Step6: Snatch main func (cont.) -- ### native-activity/hs_src/Main.hs ### main :: IO () -- Dummy main = return () foreign export ccall "androidMain" androidMain :: Ptr AndroidApp > IO () androidMain :: Ptr AndroidApp -> IO () -- True main androidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek app let apphs' = apphs { appUserData = eng, appOnAppCmd = p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng -- Prepare to monitor accelerometer sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETER let looper = appLooper apphs' when (ss_p /= nullPtr) $ do ss <- peek ss_p -- snip --
  37. 37. Step6: Snatch main func // ### native-activity/jni/main.c ### void android_main(struct android_app* app_dummy(); // Make sure glue // Init & run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv; } hs_init(&hsargc, &hsargvp); androidMain(state); hs_exit(); state) { isn't stripped.
  38. 38. Step7: Get clear => GOAL We are in the strong typed world. Haskell's turn, now!
  39. 39. PR: Call For Articles ☆ http://www.paraiso-lang.org/ikmsm/ ☆ Fanzine of functional programming. ☆ About Haskell or OCaml or . . . ☆ Article about Ajhc in C84 book. ☆ Call me if you read it! http://www.paraiso-lang.org/ikmsm/books/c85.html
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×