Ho pensato a questo problema che stavo vivendo. Ho un design di tipo produttore-consumatore con due mittenti di compiti creati dall'utente e lettore. La coda viene utilizzata per comunicare tra il lettore-mittente. Attualmente la cosa funziona, ma sto inviando una struttura grezza nella coda, che contiene tutti i possibili datamembers per ogni possibile Gcodecommand.
Stavo pensando a una soluzione diversa, come segue ... Fondamentalmente sto ancora facendo un brainstorming a questo punto ... Un po 'come la conversazione gommosa in programmazione ...
Ho diversi tipi di comandi Gcode, che dovrebbero essere probabilmente classi diverse (i datamembers sono di numero variabile, ma sono combinazioni di bool e di interi)
esempi per le classi:
- comando M1, bool isLegal
- Comando M2, bool isLegal, int pencilServoValue
- Comando G1, bool isLegal, int XcoordHundredths, YcoordHundredths
- Comando M5, bool isLegal, bool XMotorClockwise, bool YMotorClockwise, int height, int width, int speed
- ecc ...
Forse potrei avere un altro oggetto avvolto, che in realtà è il tipo di oggetto che viene inviato in coda.
- dataPacket, enum {M1, M2, G1 ...} baseType, void * commandAddress
Non sono sicuro che tu sia autorizzato a usare un puntatore vuoto come quello ... Preferirei avere un datamember di puntatore all'interno di dataPacket, ma dovrebbe essere in grado di accettare qualsiasi "Puntatore di comando" come datamember, ovviamente ...
Questo significa che dovrei ereditare tutti i comandi Gcode da una classe di riferimento comune e avere un puntatore di classe base come datamember dataPacket?
SE, faccio questo con il puntatore della classe di base, devo quindi implementare il distruttore in un certo modo, come un distruttore virtuale o qualcosa del genere?
In modo che il distruttore corretto venga sempre chiamato per qualsiasi classe derivata?
Quindi, per un caso d'uso,
Potrei ammucchiare-allocare con un nuovo operatore un comando particolare, e inserire l'indirizzo in dataPacket e configurare il dataPacket con baseType corretto. Heap-allocate proteggerebbe il puntatore, per tutta la sua durata all'interno della coda, immagino ... ma sembra sempre che usare l'allocazione dell'heap sarebbe un po 'lento e inefficiente per il codice?
Quindi, potrei inviare il dataPacket in coda.
Quindi, reader_task può leggere cosa c'è dentro il dataPacket ed eliminare il puntatore per liberare la memoria per evitare perdite di memoria.
Mi chiedevo anche quale sarebbe stato un buon accumulo di tempo per l'uso di FreeRTOS in questo tipo di casi d'uso? Le allocazioni con il nuovo operatore saranno ovviamente un caso comune ... e idealmente, naturalmente, i puntatori dovrebbero essere al sicuro durante il tempo trascorso in attesa all'interno della coda.
Penso che ci sarà un solo produttore e un compito per i consumatori.