Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

GOLang, RFID i C - HardGroup Langs #1

234 views

Published on

Pamiętacie jeszcze prezentację o RFID i raspberry? Teraz czeka nas powrót do problemu. Wrócę do omawianych problemów i pokażę jak zdecydowałem się je rozwiązać. Dlaczego poprzednie rozwiązanie było błędne.
Posłuchamy o c, golang i sprzęcie. Czyli o nowym języku od google i jego zastosowaniach w mikrokomputerach. Podczas prezentacji omówię podstawową składnię go. Poruszę temat cgo, mieszania go z c i programowania niskopoziomowym. Poruszę temat współbieżności i udowodnię, że programowanie współbieżne to nie tylko domena wielkich serwerów.
Kod open source:
https://github.com/firmom/go-rfid-rc522

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

GOLang, RFID i C - HardGroup Langs #1

  1. 1. GOLang & RFID
  2. 2. Co to RFID?
  3. 3. “RFID (ang. Radio-frequency identification) – technika, która wykorzystuje fale radiowe do przesyłania danych oraz zasilania elektronicznego układu (etykieta RFID) stanowiącego etykietę obiektu przez czytnik, w celu identyfikacji obiektu.” - Wikipedia
  4. 4. Zarys historyczny
  5. 5. GOLang
  6. 6. CGO
  7. 7. Import C // #include <stdio.h> // #include <errno.h> import "C" // #cgo CFLAGS: -DPNG_DEBUG=1 // #cgo amd64 386 CFLAGS: -DX86=1 // #cgo LDFLAGS: -lpng // #include <png.h> import "C" // #cgo pkg-config: png cairo // #include <png.h> import "C"
  8. 8. Referencje do C package main // typedef int (*intFunc) (); // int // bridge_int_func(intFunc f) // { // return f(); // } // int fortytwo() // { // return 42; // } import "C" import "fmt" func main() { f := C.intFunc(C.fortytwo) fmt.Println(int(C.bridge_int_func(f))) // Output: 42 }
  9. 9. Typy func C.CString(string) *C.char func C.CBytes([]byte) unsafe.Pointer func C.GoString(*C.char) string func C.GoStringN(*C.char, C.int) string func C.GoBytes(unsafe.Pointer, C.int) []byte
  10. 10. GO w C //export MyFunction func MyFunction(arg1, arg2 int, arg3 string) int64 {...} //export MyFunction2 func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...} extern int64 MyFunction(int arg1, int arg2, GoString arg3); extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);
  11. 11. Budujemy ● Na rpi ● Na pc > GOARM=6 GOARCH=arm GOOS=linux go build examples/raspi_blink.go > go build -ldflags "-w" .main.go
  12. 12. RFID - Aplikacja
  13. 13. Main func main() { reader, _ := rc522.NewRfidReader() readerChan, _ := rfid.NewReaderChan(reader) rfidChan := readerChan.GetChan() doSomethingCount := 0 for { select { case id := <-rfidChan: fmt.Println(id) default: doSomethingCount++ fmt.Println(" ... ", doSomethingCount) time.Sleep(1000 * time.Millisecond) } } }
  14. 14. Interfejs package rfid type RfidReader interface { ReadId() (string, error) }
  15. 15. Kanał do odczytu danych type ReaderChan struct { reader RfidReader ch chan string } func NewReaderChan(reader RfidReader) (*ReaderChan, error) { reducReader, err := NewReducer(reader) if err != nil { return nil, err } c := &ReaderChan{ reader: reducReader, ch: make(chan string, 1), } go c.loop() return c, nil }
  16. 16. Odczyt z pętli func (c *ReaderChan) loop() { for { id, err := c.reader.ReadId() if err != nil { continue } c.ch <- id } } func (c *ReaderChan) ReadId() (string, error) { return <-c.ch, nil } func (c *ReaderChan) GetChan() chan string { return c.ch }
  17. 17. Reducer func (r *Reducer) ReadId() (string, error) { id, err := r.reader.ReadId() if err != nil { r.oldvalue = "" return id, err } if id == r.oldvalue { return id, fmt.Errorf("RFID: duplicate id echo") } r.oldvalue = id return id, err }
  18. 18. RFID - Adapter C
  19. 19. Nagłówek package rc522 // #cgo CFLAGS: -I${SRCDIR}/libs/ // #cgo LDFLAGS: -L${SRCDIR}/libs/ -lbcm2835 // #include <rc522_public.c> import "C" import ( "fmt" rfid "github.com/firmom/go-rfid-rc522/rfid" ) var ( instance rfid.RfidReader = nil )
  20. 20. RfidReader type RfidReader struct{} func NewRfidReader() (rfid.RfidReader, error) { if instance == nil { errCode, err := C.InitRC522RfidReader() if err != nil { return nil, err } if errCode != 0 { return nil, fmt.Errorf("Init rc522 fail with code: %s", errCode) } instance = rfid.RfidReader(RfidReader{}) } return instance, nil }
  21. 21. Odczyt z czytnika func (r RfidReader) ReadId() (string, error) { response, err := C.ReadIdByRC522() if err != nil { return "", err } if response.errorCode != C.NO_ERROR { return "", fmt.Errorf("Read rc522 fail with code: %s", response.errorCode) } return C.GoString(&response.id[0]), nil }
  22. 22. RFID - Czysty C
  23. 23. Odczyt z czytnika uint8_t InitRC522RfidReader(void) { uint16_t sp; sp = (uint16_t) (250000L / DEFAULT_SPI_SPEED); if (!bcm2835_init()) { return 1; } bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default bcm2835_spi_setClockDivider(sp); // The default bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default InitRc522(); return 0; }
  24. 24. Inicjalizacja rc522 void InitRc522(void) { PcdReset(); PcdAntennaOn(); }
  25. 25. Odczyt struct CardIdResult ReadIdByRC522() { //vars... statusRfidReader = find_tag(&CType); if (statusRfidReader == TAG_NOTAG) { //... } else if (statusRfidReader != TAG_OK && statusRfidReader != TAG_COLLISION) { //... } if (select_tag_sn(serialNumber, &serialNumberLength) != TAG_OK) { //... } p = result.id; for (loopCounter = 0; loopCounter < serialNumberLength; loopCounter++) { sprintf(p, "%02x", serialNumber[loopCounter]); p += 2; } *(p++) = 0; result.status = TAG_STATUS; result.errorCode = NO_ERROR; return result; }
  26. 26. Czas na demo
  27. 27. Pytania?
  28. 28. go-rfid-rc522 https://github.com/firmom/go-rfid-rc522
  29. 29. Dziękuję za uwagę

×