Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter ๐Ÿ’™ Embedded @ I/O Extended 2023 Incheon ...

Flutter ๐Ÿ’™ Embedded @ I/O Extended 2023 Incheonย (๋ฐ•์ œ์ฐฝ)

Flutter ๐Ÿ’™ Embedded @ I/O Extended 2023 Incheon (๋ฐ•์ œ์ฐฝ)

JaiChangPark

August 26, 2023
Tweet

More Decks by JaiChangPark

Other Decks in Programming

Transcript

  1. 16 Intro Source: https://coral.ai/products/som https://coral.ai/products/dev-board CPU NXP i.MX 8M SoC

    (quad Cortex-A53, Cortex-M4F) GPU Integrated GC7000 Lite Graphics ML accelerator Google Edge TPU coprocessor: 4 TOPS (int8); 2 TOPS per watt System-on-Module (SoM)
  2. 26 Section 01 โ€ข ์„ค๋ฆฝ: 2009๋…„ 5์›” โ€ข ์ฐฝ๋ฆฝ์ž: David

    Braben, Jack Lang, Alan Mycroft, Robert Mullins, Eben Upton โ€ข ํ™œ๋™: The object of the charity is to further the advancement of education of adults and children, particularly in the field of Computers, Computer Science and related subjects Raspberry Pi Foundation
  3. 27 Section 01 Raspberry Pi Foundation 2009๋…„ 2016 2018 Raspberry

    Pi Ltd Raspberry Pi Foundation Headquarters ์ถœ์ฒ˜: https://en.wikipedia.org/wiki/Raspberry_Pi_Foundation#/media/File:RpiFoundationHeadquarters.jpg
  4. 28 Section 01 Raspberry Pi Foundation โ€ข Eben owned a

    BBC Micro as a kid, and as an adult he set about designing Raspberry Pi to do what the BBC Micro had done for him: inspire widespread interest in computer programming. โ€ข As a Director of Studies, he noticed a decline in the number of students applying to study computer science, and had an idea: he thought that if he could get affordable hardware into the hands of young people at the right point, it could spark an interest in taking computing further. https://www.raspberrypi.com/news/the-bbc-micro-and-raspberry-pi/ https://spectrum.ieee.org/eben-upton-on-the-raspberry-pis-industrial-crossover-and-why-there-will-never-be-a-pi-9
  5. 32 Section 01 BBC Micro:Bit https://en.wikipedia.org/wiki/Micro_Bit โ€ข Release date โ—ฆ

    v1: 10 February 2016 โ—ฆ v2: 13 October 2020 โ€ข CPU โ—ฆ v1: Nordic nRF51822, 16 MHz ARM Cortex-M0 core, 256 KB Flash, 16 KB RAM โ—ฆ v2: Nordic nRF52833, 64 MHz ARM Cortex-M4 core, 512 KB Flash, 128 KB RAM
  6. 33 Section 01 โ€ข ์ˆ˜์ต: ยฃ112,663,267 (192,266,445,008์›) โ€ข ์ง€์ถœ: ยฃ101,823,872

    (173,768,384,387์›) โ€ข 31 December 2021 ๊ธฐ์ค€ Raspberry Pi Foundation ์ถœ์ฒ˜ https://register-of-charities.charitycommission.gov.uk/charity-search/-/charity-details/5002372
  7. Section 01 ์ถœ์ฒ˜ https://www.raspberrypi.com/news/logo-competition-we-have-a-winner/ https://en.wikipedia.org/wiki/Buckminsterfullerene โ€ข Created by Paul Beech

    โ€ข Buckminsterfullerene(=ํ’€๋ ˆ๋ Œ) โ—ฆ 32 Face โ—ฆ 11 are visible in the logo โ€ข The Raspberry Pi has โ—ฆ a 32-bit processor and an ARM11 on board 35
  8. 36 Section 01 Raspberry Pi - 1 (2012) https://www.sparkfun.com/products/retired/11546 https://en.wikipedia.org/wiki/Raspberry_Pi

    โ€ข CPU: Broadcom BCM2835 SoC โ—ฆ 700 MHz ARM1176JZF-S core CPU โ€ข GPU: Broadcom VideoCore IV GPU โ€ข 512 MB RAM โ€ข 2 x USB2.0 Ports โ€ข Storage: SD/MMC/SDIO โ€ข GPIO 26 โ€ข Full HD 1080p
  9. 37 Section 01 Raspberry Pi - 2 (2015) https://en.wikipedia.org/wiki/Raspberry_Pi โ€ข

    CPU: Broadcom BCM2836 / 7 SoC โ—ฆ 900MHz quad-core ARM Cortex-A7 CPU (32bit) โ—ฆ 900 MHz ARM Cortex-A53 (64bit) โ€ข GPU: VideoCore IV MP2 250 MHz โ€ข 1GB LPDDR2 RAM โ€ข 40 GPIO โ€ข Full HD 1080p โ€ข 4 x USB2.0 Ports โ€ข
  10. 38 Section 01 Raspberry Pi - 3 (2018) https://en.wikipedia.org/wiki/Raspberry_Pi โ€ข

    CPU: Broadcom BCM2837B0 SoC โ—ฆ 1.5GHz ARM Cortex-A53 (64 bit) โ€ข GPU: VideoCore IV MP2 250 MHz โ€ข 1GB LPDDR2 RAM โ€ข 40 GPIO โ€ข 2 x USB2.0 Ports โ€ข Full HD 1080p โ€ข Wi-Fi, BLE 4.x
  11. 39 Section 01 Raspberry Pi - 4 (2019) https://en.wikipedia.org/wiki/Raspberry_Pi โ€ข

    CPU: Broadcom BCM2711 SoC โ—ฆ 1.5GHz ARM Cortex-A72 (64 bit) โ€ข GPU: VideoCore IV MP2 500 MHz โ€ข RAM: 1, 2, 4, 8GB LPDDR4-3200 SDRAM โ€ข 40 GPIO โ€ข 2 x USB2.0 Ports โ€ข 2 x USB3.0 Ports โ€ข Wi-Fi, BLE 5 โ€ข Dual displays 4K output โ€ข 2 x Micro HDMI
  12. 42 Section 01 Raspberry Pi OS Raspbian is a free

    operating system based on Debian optimized for the Raspberry Pi hardware. Raspbian โ†’ Raspberry Pi OS
  13. 43 Section 01 Raspberry Pi OS 2023-05-03: * 64-bit Mathematica

    added to rp-prefapps * Bug fix - occasional segfault in CPU temperature plugin * Bug fix - X server crash when changing screen orientation * Bug fix - X server DPMS not working * Mathematica updated to 13.2.1 * Matlab updated to 23.1.0 * Chromium updated to 113.0.5672.59 * Raspberry Pi Imager updated to 1.7.4 * RealVNC server updated to 7.0.1.49073 * RealVNC viewer updated to 7.0.1.48981 * Updated VLC HW acceleration patch * libcamera - Add generalised statistics handling. - Fix overflow that would cause incorrect calculations in the AGC algorithm. - Improve IMX296 sensor tuning. * libcamera-apps - Improve handling of audio resampling and encoding using libav - Improve performance of QT preview window rendering - Add support for 16-bit Bayer in the DNG writer - Fix for encoder lockup when framerate is set to 0 - Improved thumbnail rendering * picamera2 - MJPEG server example that uses the hardware MJPEG encoder. - Example showing preview from two cameras in a single Qt app. - H264 encoder accepts frame time interval for SPS headers. - H264 encoder should advertise correct profile/level. - H264 encoder supports constant quality parameter. - Exif DateTime and DateTimeOriginal tags are now added. - Various bug fixes (check Picamera2 release notes for more details). * Some translations added * Raspberry Pi firmware 055e044d5359ded1aacc5a17a8e35365373d0b8b * Linux kernel 6.1.21 https://downloads.raspberrypi.org/raspios_arm64/release_notes.txt
  14. 45 Section 01 Raspberry Pi GPIO โ€ข https://pinout.xyz/ โ€ข Pin

    Map์„ ๋ชจ๋‘ ์™ธ์šฐ๊ธฐ ์–ด๋ ค์šด ๋ถ„๋“ค์„ ์œ„ํ•œ โ€ฆ โ€ข ์ถœ๋ ฅ์„ ํ•ด์„œ ๋ณด๊ฑฐ๋‚˜ ์›น์—์„œ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒ€์ƒ‰
  15. 46 Section 01 Raspberry Pi 1. ๊ฐ€๊ฒฉ 2. ๋ฆฌ๋ˆ…์Šค ๋ฒ ์ด์Šค

    OS ์„ค์น˜ ๊ฐ€๋Šฅ 3. SD ์นด๋“œ ์†๋„ ๋ฐ ๊ทธ ์™ธ ์ด์Šˆ
  16. 48 Section 02 ์ค€๋น„ํ•˜๊ธฐ https://www.raspberrypi.com/software/raspberry-pi-desktop/ โ€ข ์ €๋ ดํ•œ ์ปดํ“จํ„ฐ๋ผ๊ณ  ํ–ˆ์ง€๋งŒ ์ปดํ“จํ„ฐ

    ์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์–ด๋–ค๊ฒƒ๋“ค์ด ํ•„์š”ํ• ๊นŒ์š”? โ€ข ์–ด๋Š ์ •๋„ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ
  17. 49 ์ค€๋น„ํ•˜๊ธฐ โ€ข ์ €๋ ดํ•œ ์ปดํ“จํ„ฐ๋ผ๊ณ  ํ–ˆ์ง€๋งŒ ์ปดํ“จํ„ฐ ์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์–ด๋–ค๊ฒƒ๋“ค์ด

    ํ•„์š”ํ• ๊นŒ์š”? 1. RPi 2. ๋งˆ์šฐ์Šค 3. ํ‚ค๋ณด๋“œ 4. Monitors & Display 5. HDMI Cable 6. SD Card 7. SD Card Reader 8. ๋ฐฉ์—ดํŒ & ํŒฌ 9. (์˜ต์…˜) ์ผ€์ด์Šค 10. ์ „์› ์–ด๋Œ‘ํ„ฐ 11. ์ด๋”๋„ท ์ผ€์ด๋ธ” 12. ์Šคํ”ผ์ปค Section 02
  18. 51 ์ค€๋น„ํ•˜๊ธฐ Camera - CSI Camera Serial Interface Section 02

    https://projects.raspberrypi.org/en/projects/getting-started-with-picamera
  19. 54 ์ค€๋น„ํ•˜๊ธฐ - Model 4 1. RPi - ๊ธฐ๋ณธ ๊ตฌ๋งค

    2. ๋งˆ์šฐ์Šค - ๊ตฌ๋งค 3. ํ‚ค๋ณด๋“œ - ๊ตฌ๋งค 4. Monitors & Display - ๊ตฌ๋งค 5. HDMI Cable - ๊ตฌ๋งค 6. SD Card - ๊ตฌ๋งค 7. SD Card Reader - ๊ตฌ๋งค 8. ๋ฐฉ์—ดํŒ & ํŒฌ - ๊ตฌ๋งค 9. (์˜ต์…˜) ์ผ€์ด์Šค - ๊ตฌ๋งค 10. ์ „์› ์–ด๋Œ‘ํ„ฐ - ๊ตฌ๋งค 11. ์ด๋”๋„ท ์ผ€์ด๋ธ” - ๊ตฌ๋งค 12. ์Šคํ”ผ์ปค - ๊ตฌ๋งค ์ถ”๊ฐ€ ๊ตฌ๋งค 13. HDMI - HDMI Micro Adapter & ์ผ€์ด๋ธ” 14. ์ „์› Adapter Usb - C 15. Micro-B to C ๐Ÿ’ธ Section 02
  20. 56 ์ค€๋น„ํ•˜๊ธฐ https://www.waveshare.com/game-hat.htm โ€ข 3.5inch IPS screen, 480 ร— 320

    resolution. โ€ข 60 frame experience, smooth display, no more frame loss. โ€ข Compatible with Raspberry Pi A+/B+/2B/3B/3B+/4B (Raspberry Pi Zero/Zero W/Zero WH requires another HDMI cable). โ€ข Integrates battery charge circuitry, powered from a 18650 lithium battery (NOT included), plays anywhere anytime. โ€ข Battery capacity indicator. โ€ข Onboard speaker and earphone jack, listen to the familiar BGM from the old days. Section 02 I/O 23 Flutter, Dart, and Raspberry Pi
  21. 58 Intro Section 02 1. ํ•˜๋“œ์›จ์–ด ์…‹ํŒ… ๋ฐ ๊ฒฐํ•ฉํ•˜๊ธฐ 2.

    SD Card ์ดˆ๊ธฐํ™” 3. OS ์„ค์น˜ํ•˜๊ธฐ โ†’ OS๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•œ PC๊ฐ€ ํ•„์š” 4. ์ „์› ์ธ๊ฐ€ ๋ฐ ๋ถ€ํŒ… ํ™•์ธํ•˜๊ธฐ
  22. 66 Section 03 Install Flutter โ€ข Raspberry Pi OS โ‡’

    Debian โ‡’ Linux โ€ข Operating Systems: Linux (64-bit) โ€ข Disk Space: 600 MB (does not include disk space for IDE/tools). โ€ข Tools: Flutter depends on these command-line tools being available in your environment.
  23. 67 Section 03 Install Flutter Tools: Flutter depends on these

    command-line tools being available in your environment. bash, curl, file, git 2.x, mkdir, rm, unzip, which, xz-utils, zip Shared libraries: Flutter test command depends on this library being available in your environment. libGLU.so.1 - provided by mesa packages such as libglu1-mesa on Ubuntu/Debian and mesa-libGLU on Fedora.
  24. 71 Section 03 UI Toolkit 1. GTK : GNOME 2.

    Qt 3. SDL : OSS 4. WebKit : Apple 5. Flutter : Google 6. Kotlin Multiplatform : Jet Brains 7. Unity 8. โ€ฆ
  25. 74 Section 04 Push Button Push Button Push Button Push

    Button Push Button Push Button Display 1 2
  26. 76 Section 04 BCM2711 https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf โ€ข There are 58 General-Purpose

    Input/Output (GPIO) lines split into three banks. โ€ข Bank 0 contains GPIOs 0 to 27, bank 1 contains GPIOs 28 to 45, and bank 2 contains GPIOs 46 to 57. โ€ข All GPIO pins have at least two alternative functions within BCM2711. โ€ข The alternate functions are usually peripheral IO, and a single peripheral may appear in multiple banks to allow flexibility on the choice of IO voltage (as each bank has a selectable IO voltage).
  27. rpi_gpio_ext.cc int64_t setupGpio() { int fd = open("/dev/gpiomem", O_RDWR |

    O_SYNC | O_CLOEXEC); if (fd < 0) return -1; void *gpio_map = mmap( 0, // Any adddress in our space will do BLOCK_SIZE, // Map length PROT_READ | PROT_WRITE, // Enable reading & writting to mapped memory MAP_SHARED, // Shared with other processes fd, // File to map 0x3F200000 // Offset to GPIO peripheral ); 82 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/native/rpi_gpio_ext.cc
  28. #if defined( RPI0 ) || defined( RPI1 ) #define GPIO_BASE

    0x20200000UL #elif defined( RPI2 ) || defined( RPI3 ) #define GPIO_BASE 0x3F200000UL #elif defined( RPI4 ) #define GPIO_BASE 0xFE200000UL #else #error Unknown RPI Model! #endif 83
  29. void setGpioMode(int bcmGpioPin, int mode) { int offset = bcmGpioPin

    / 10; int shift = (bcmGpioPin % 10) * 3; *(gpio + offset) = (*(gpio + offset) & ~(7 << shift)) | ((mode & 0x7) << shift); } 84 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/native/rpi_gpio_ext.cc rpi_gpio_ext.cc
  30. void setGpioInput(int64_t bcmGpioPin, int64_t pullUpDown) { setGpioMode(bcmGpioPin, FSEL_INPT); // 37

    is GPIO up/down register, 38 and 39 are GPIO up/down set bits *(gpio + 37) = pullUpDown & 3; delayMicroseconds (5); *(gpio + (bcmGpioPin < 32 ? 38 : 39)) = 1 << (bcmGpioPin & 31); delayMicroseconds (5); *(gpio + 37) = 0; delayMicroseconds (5); *(gpio + (bcmGpioPin < 32 ? 38 : 39)) = 0; delayMicroseconds (5); } 85 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/native/rpi_gpio_ext.cc rpi_gpio_ext.cc
  31. // Read the input voltage on a GPIO pin and

    return either true (high) or false (low). int64_t readGpio(int64_t bcmGpioPin) { // 13 and 14 are GPIO input bits return (*(gpio + (bcmGpioPin < 32 ? 13 : 14)) & (1 << (bcmGpioPin & 31))); } // Set the output voltage on a GPIO pin to high (true, non-zero) or low (false, zero). void writeGpio(int64_t bcmGpioPin, int64_t newValue) { // 7 and 8 are set GPIO output HIGH bits, 10 and 11 are set GPIO output LOW bits. *(gpio + (newValue != 0 ? 7 : 10) + (bcmGpioPin < 32 ? 0 : 1)) = 1 << (bcmGpioPin & 31); } 86 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/native/rpi_gpio_ext.cc rpi_gpio_ext.cc
  32. g++ -fPIC -c rpi_gpio_ext.cc # use --no-undefined to check for

    missing libraries gcc -shared -lpthread -Wl,-soname,librpi_gpio_ext.so -o librpi_gpio_ext.so rpi_gpio_ext.o # Copy the library cp librpi_gpio_ext.so ../librpi_gpio_ext.so 88 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/native/rpi_gpio_ext.cc build_native
  33. void main(List<String> args) { final nativeDir = Directory(join(pkgRootDir.path, 'lib', 'src',

    'native')); final buildScriptFile = File(join(nativeDir.path, 'build_native')); assertRunningOnRaspberryPi(); final buildResult = Process.runSync(buildScriptFile.path, []); } 89 https://github.com/danrubel/rpi_gpio.dart/blob/main/bin/build_native.dart build_native.dart
  34. ffi.DynamicLibrary findDynamicLibrary() { String libName; if (Platform.isLinux) { libName =

    'librpi_gpio_ext.so'; } else { // Windows: Debug\rpi_gpio_ext.dll // MacOS: librpi_gpio_ext.dylib throw 'Unsupported OS: ${Platform.operatingSystem}'; } /// } 91 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/rpi_gpio_isolate.dart rpi_gpio_isolate.dart
  35. class RpiGpioLibImpl implements RpiGpioLib { final int Function() _setupGpio; final

    int Function() _disposeGpio; final void Function(int, int) _setGpioInput; final int Function(int) _readGpio; final void Function(int) _setGpioOutput; final void Function(int, int) _writeGpio; 92 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/rpi_gpio_isolate.dart rpi_gpio_isolate.dart
  36. RpiGpioLibImpl(ffi.DynamicLibrary dylib) : _setupGpio = dylib .lookup<ffi.NativeFunction<ffi.Int64 Function()>>('setupGpio') .asFunction<int Function()>(),

    _setGpioInput = dylib .lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.Int64)>>('setGpioInput') .asFunction<void Function(int, int)>(), _readGpio = dylib .lookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Int64)>>('readGpio') .asFunction<int Function(int)>(), 93 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/rpi_gpio_isolate.dart rpi_gpio_isolate.dart
  37. void isolateMain(SendPort sendPort) { final gpioLib = RpiGpioLibImpl(findDynamicLibrary()); final cmdHandler

    = RpiGpioCmdHandler(sendPort, gpioLib); var receivePort = ReceivePort(); sendPort.send(comm.initCompleteRsp(receivePort.sendPort)); receivePort.listen((data) { comm.dispatchCmd(data, cmdHandler); }); } 94 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/rpi_gpio_isolate.dart rpi_gpio_isolate.dart
  38. Future<RpiGpio> initialize_RpiGpio({ Completer<GpioException>? onError, }) => RpiGpio.init( onError: onError, isolateEntryPoint:

    isolateMain, ); 95 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/rpi_gpio.dart rpi_gpio.dart
  39. class RpiGpio extends Gpio { static bool _instantiatedGpio = false;

    late SendPort _sendPort; late StreamSubscription _receivePortSubscription; late StreamSubscription _onErrorSubscription; final Completer<GpioException>? _onError; late _RpiGpioResponseHandler _rspHandler; 96 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/rpi_gpio.dart rpi_gpio.dart
  40. abstract class Gpio { final _allocatedPins = <int>[]; Future dispose();

    GpioInput input(int physicalPin, [Pull pull = Pull.off]); GpioOutput output(int physicalPin); /// } 97 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/gpio.dart gpio.dart
  41. class _ChangedValueTransformer<T> extends StreamTransformerBase<T, T> { StreamController<T>? _controller; T? lastValue;

    @override Stream<T> bind(Stream<T> stream) { late StreamSubscription<T> subscription; _controller = StreamController<T>(onListen: () { subscription = stream.listen((T newValue) { if (newValue != lastValue) { _controller!.add(newValue); lastValue = newValue; } });}, onCancel: () { subscription.cancel(); }); return _controller!.stream; } } 98 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/gpio.dart gpio.dart
  42. static Future<RpiGpio> init({ Completer<GpioException>? onError, required Function(SendPort sendPort) isolateEntryPoint, SendPort?

    testSendPort, }) async { const timeout = Duration(seconds: 30); final rpiGpio = RpiGpio._(onError, i2c: i2c, spi: spi, eeprom: eeprom); await Isolate.spawn(isolateEntryPoint, receivePort.sendPort, onError: onErrorPort.sendPort); try { await rspHandler.initCompleter.future.timeout(timeout); } on TimeoutException { /// } catch (error) { /// } return rpiGpio .._receivePortSubscription = receivePortSubscription .._onErrorSubscription = onErrorSubscription .._rspHandler = rspHandler; } 100 https://github.com/danrubel/rpi_gpio.dart/blob/main/lib/src/rpi_gpio_impl.dart rpi_gpio_impl.dart
  43. final button = gpio.input(11, Pull.up); bool lastValue = true; int

    count = 0; final completer = Completer(); final subscription = button.values .transform(Debouncer(lastValue, debounce)) .listen((bool newValue) { print('New button state: $newValue'); if (lastValue == false && newValue) { ++count; if (count == 3) { completer.complete(); } } led.value = lastValue = newValue; }); 102 app.dart
  44. Section 04 103 Flutter, Dart, and Raspberry Pi Flutter Embedded

    https://youtu.be/jW3pqIpQtQE 2022-03-05
  45. Section 04 104 Flutter, Dart, and Raspberry Pi Flutter Embedded

    https://youtu.be/jW3pqIpQtQE 2022-03-05
  46. 105 Summary 1. Embedded System์—์„œ Flutter ์‚ฌ์šฉ ๊ฐ€๋Šฅ a. Flutter

    2.2๋ถ€ํ„ฐ ARM64 Linux Host ์ง€์› 2. Raspberry Pi a. Rpi 4 b. Raspberry Pi OS โ‡’ Debian 3. Rpi Flutter a. Flutter Linux๋กœ ์„ค์น˜ 4. GPIO a. ๋ ˆ์ง€์Šคํ„ฐ ๊ธฐ๋ฐ˜ b. Flutter gpio ํ™œ์šฉ ํŒจํ‚ค์ง€๋„ ์กด์žฌ c. ffi ์— ๋Œ€ํ•œ ์ดํ•ด์™€ ์‚ฌ์šฉ