clean up arch

This commit is contained in:
2025-11-02 10:57:53 +01:00
parent abcc3e0b5e
commit 15d0f8b61b
11 changed files with 175 additions and 334 deletions

View File

@@ -3,6 +3,7 @@ package hardware
import (
"context"
_ "embed"
"errors"
"fmt"
goRuntime "runtime"
"sync"
@@ -19,20 +20,21 @@ import (
*/
import "C"
// FTDIFinder represents how the protocol is defined
// FTDIFinder manages all the FTDI peripherals
type FTDIFinder struct {
findTicker time.Ticker // Peripherals find ticker
wg sync.WaitGroup
findTicker *time.Ticker // Peripherals find ticker
foundPeripherals map[string]PeripheralInfo // The list of peripherals handled by this finder
registeredPeripherals map[string]*FTDIPeripheral // The list of found peripherals
scanChannel chan struct{} // The channel to trigger a scan event
goWait sync.WaitGroup // Check goroutines execution
}
// NewFTDIFinder creates a new FTDI finder
func NewFTDIFinder(findPeriod time.Duration) *FTDIFinder {
log.Trace().Str("file", "FTDIFinder").Msg("FTDI finder created")
return &FTDIFinder{
findTicker: *time.NewTicker(findPeriod),
findTicker: time.NewTicker(findPeriod),
foundPeripherals: make(map[string]PeripheralInfo),
registeredPeripherals: make(map[string]*FTDIPeripheral),
scanChannel: make(chan struct{}),
@@ -41,12 +43,15 @@ func NewFTDIFinder(findPeriod time.Duration) *FTDIFinder {
// RegisterPeripheral registers a new peripheral
func (f *FTDIFinder) RegisterPeripheral(ctx context.Context, peripheralData PeripheralInfo) (string, error) {
// Create a new FTDI peripheral
ftdiPeripheral, err := NewFTDIPeripheral(peripheralData)
if err != nil {
return "", fmt.Errorf("unable to create the FTDI peripheral: %v", err)
}
// Register it in the finder
f.registeredPeripherals[peripheralData.SerialNumber] = ftdiPeripheral
log.Trace().Any("periph", &ftdiPeripheral).Str("file", "FTDIFinder").Str("peripheralName", peripheralData.Name).Msg("FTDI peripheral has been created")
// Peripheral created, connect it
err = ftdiPeripheral.Connect(ctx)
if err != nil {
@@ -71,7 +76,7 @@ func (f *FTDIFinder) UnregisterPeripheral(ctx context.Context, peripheralID stri
return err
}
// Disconnecting peripheral
err = peripheral.Disconnect(ctx)
err = peripheral.Disconnect()
if err != nil {
return err
}
@@ -93,9 +98,9 @@ func (f *FTDIFinder) Initialize() error {
// Start starts the finder and search for peripherals
func (f *FTDIFinder) Start(ctx context.Context) error {
f.goWait.Add(1)
f.wg.Add(1)
go func() {
defer f.goWait.Done()
defer f.wg.Done()
for {
select {
case <-ctx.Done():
@@ -120,18 +125,11 @@ func (f *FTDIFinder) Start(ctx context.Context) error {
// ForceScan explicily asks for scanning peripherals
func (f *FTDIFinder) ForceScan() {
f.scanChannel <- struct{}{}
}
// Stop stops the finder
func (f *FTDIFinder) Stop() error {
log.Trace().Str("file", "FTDIFinder").Msg("stopping the FTDI finder...")
// Wait for goroutines to stop
f.goWait.Wait()
// Stop the ticker
f.findTicker.Stop()
log.Trace().Str("file", "FTDIFinder").Msg("FTDI finder stopped")
return nil
select {
case f.scanChannel <- struct{}{}:
default:
// Ignore if the channel is full or if it is closed
}
}
// GetName returns the name of the driver
@@ -171,18 +169,12 @@ func (f *FTDIFinder) scanPeripherals(ctx context.Context) error {
log.Info().Int("number", count).Msg("number of FTDI devices connected")
// Alloue un tableau de structures côté C
// Allocating C array
size := C.size_t(count) * C.size_t(unsafe.Sizeof(C.FTDIPeripheralC{}))
devicesPtr := C.malloc(size)
defer C.free(devicesPtr)
devices := (*[1 << 30]C.FTDIPeripheralC)(devicesPtr)[:count:count]
type device struct {
SerialNumber string
Description string
IsOpen bool
}
devices := (*[1 << 20]C.FTDIPeripheralC)(devicesPtr)[:count:count]
C.get_ftdi_devices((*C.FTDIPeripheralC)(devicesPtr), C.int(count))
@@ -202,7 +194,7 @@ func (f *FTDIFinder) scanPeripherals(ctx context.Context) error {
ProtocolName: "FTDI",
}
// Libération mémoire allouée côté C
// Free C memory
C.free_ftdi_device(&d)
}
@@ -214,3 +206,34 @@ func (f *FTDIFinder) scanPeripherals(ctx context.Context) error {
f.foundPeripherals = temporaryPeripherals
return nil
}
// WaitStop stops the finder
func (f *FTDIFinder) WaitStop() error {
log.Trace().Str("file", "FTDIFinder").Msg("stopping the FTDI finder...")
// Stop the ticker
f.findTicker.Stop()
// Close the channel
close(f.scanChannel)
// Wait for all the peripherals to close
log.Trace().Str("file", "FTDIFinder").Msg("closing all FTDI peripherals")
var errs []error
for registeredPeripheralSN, registeredPeripheral := range f.registeredPeripherals {
err := registeredPeripheral.WaitStop()
if err != nil {
errs = append(errs, fmt.Errorf("%s: %w", registeredPeripheralSN, err))
}
}
// Wait for goroutines to stop
f.wg.Wait()
// Returning errors
if len(errs) > 0 {
return errors.Join(errs...)
}
log.Trace().Str("file", "FTDIFinder").Msg("FTDI finder stopped")
return nil
}