Fix memory leak in TX. Add 'heap' command. Minor refactoring & docs.

pull/4/head
CInsights 2018-04-06 02:18:31 +10:00
rodzic 8acae72d21
commit 7fddb09931
13 zmienionych plików z 180 dodań i 559 usunięć

Wyświetl plik

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="185104218123605097" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1072336591835851262" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

Wyświetl plik

@ -11,9 +11,9 @@ const conf_t conf_flash_default = {
// Primary position transmission thread
.pos_pri = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(900),
.init_delay = TIME_S2I(5)
.active = true,
.cycle = TIME_S2I(1800),
.init_delay = TIME_S2I(60)
},
.radio_conf = {
.pwr = 0x7F,

Wyświetl plik

@ -21,6 +21,7 @@ const ShellCommand commands[] = {
{"aprs_message", usb_cmd_send_aprs_message},
{"msg", usb_cmd_send_aprs_message}, /* Short form alias. */
{"test_gps", usb_cmd_set_test_gps},
{"heap", usb_cmd_ccm_heap},
{NULL, NULL}
};
@ -37,6 +38,21 @@ void usb_cmd_set_test_gps(BaseSequentialStream *chp, int argc, char *argv[])
test_gps_enabled = atoi(argv[0]);
}
void usb_cmd_ccm_heap(BaseSequentialStream *chp, int argc, char *argv[]) {
size_t n, total, largest;
(void)argv;
if (argc > 0) {
shellUsage(chp, "heap");
return;
}
extern memory_heap_t _ccm_heap;
n = chHeapStatus(&_ccm_heap, &total, &largest);
chprintf(chp, "CCM heap fragments : %u"SHELL_NEWLINE_STR, n);
chprintf(chp, "CCM heap free total : %u bytes"SHELL_NEWLINE_STR, total);
chprintf(chp, "CCM heap free largest: %u bytes"SHELL_NEWLINE_STR, largest);
}
void usb_cmd_set_trace_level(BaseSequentialStream *chp, int argc, char *argv[])
{
if(argc < 1)

Wyświetl plik

@ -11,7 +11,7 @@ void usb_cmd_printLog(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_command2Camera(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_send_aprs_message(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_set_test_gps(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_ccm_heap(BaseSequentialStream *chp, int argc, char *argv[]);
extern const ShellCommand commands[];
#endif

Wyświetl plik

@ -810,185 +810,7 @@ static void Si446x_transmitTimeoutI(thread_t *tp) {
}
/*
* Simple AFSK send thread using minimized buffering.
* Uses an iterator to size NRZI output and allocate suitably sized buffer.
* Plan is to replace with a version using even less memory.
*
*/
THD_FUNCTION(min_si_fifo_feeder_afsk, arg) {
packet_t pp = arg;
radio_unit_t radio = pp->radio;
pktAcquireRadio(radio, TIME_INFINITE);
/* Initialize radio. */
Si446x_conditional_init(radio);
Si446x_setBandParameters(radio, pp->base_frequency,
pp->radio_step);
/* Set 446x back to READY. */
Si446x_pauseReceive(radio);
Si446x_setModemAFSK_TX(radio);
/* Initialize variables for AFSK encoder. */
virtual_timer_t send_timer;
chVTObjectInit(&send_timer);
tx_iterator_t iterator;
/*
* Set NRZI encoding format.
* Iterator object.
* Packet reference.
* Preamble length (HDLC flags)
* Postamble length (HDLC flags)
* Tail length (HDLC zeros)
* Scramble off/on
*/
pktStreamIteratorInit(&iterator, pp, 30, 10, 10, false);
uint16_t all = pktStreamEncodingIterator(&iterator, NULL, 0);
//TRACE_INFO("SI > AFSK packet stream bytes %i", all);
if(all == 0) {
/* Nothing encoded. Release packet send object. */
TRACE_ERROR("SI > AFSK TX no NRZI data encoded");
// Free packet object memory
pktReleaseSendObject(pp);
/* Schedule thread memory release. */
pktScheduleThreadRelease(radio, chThdGetSelfX());
/* Exit thread. */
chThdExit(MSG_RESET);
}
/* Allocate buffer and perform NRZI encoding. */
uint8_t layer0[all];
//memset(layer0, 0, sizeof(layer0));
pktStreamEncodingIterator(&iterator, layer0, all);
all *= SAMPLES_PER_BAUD;
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
up_iterator_t upsampler = {0};
upsampler.phase_delta = PHASE_DELTA_1200;
/* Initialize variables for up sampler. */
/* phase_delta = PHASE_DELTA_1200;
phase = 0;
packet_pos = 0;
current_sample_in_baud = 0;
current_byte = 0;*/
/* Maximum amount of FIFO data when using combined TX+RX (safe size). */
uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE];
/* Get the FIFO buffer amount currently available. */
uint8_t free = Si446x_getTXfreeFIFO();
/* Calculate initial FIFO fill. */
uint16_t c = (all > free) ? free : all;
/*
* Start transmission timeout timer.
* If the 446x gets locked up we'll exit TX and release packet object.
*/
chVTSet(&send_timer, TIME_S2I(10),
(vtfunc_t)Si446x_transmitTimeoutI, chThdGetSelfX());
/* The exit message if all goes well. */
msg_t exit_msg = MSG_OK;
/* Initial FIFO load. */
for(uint16_t i = 0; i < c; i++)
//localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0);
Si446x_writeFIFO(localBuffer, c);
uint8_t lower = 0;
/* Request start of transmission. */
if(Si446x_transmit(radio,
pp->base_frequency,
pp->radio_step,
pp->radio_chan,
pp->radio_pwr,
all,
pp->cca_rssi,
TIME_S2I(10))) {
/* Feed the FIFO while data remains to be sent. */
while((all - c) > 0) {
/* Get TX FIFO free count. */
uint8_t more = Si446x_getTXfreeFIFO();
/* Update the FIFO free low water mark. */
lower = (more > lower) ? more : lower;
/* If there is more free than we need for send use remainder only. */
more = (more > (all - c)) ? (all - c) : more;
/* Load the FIFO. */
for(uint16_t i = 0; i < more; i++)
//localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0);
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
c += more;
/*
* Wait for a timeout event during up-sampled NRZI send.
* Time delay allows ~SAMPLES_PER_BAUD bytes to be consumed from FIFO.
* If no timeout event go back and load more data to FIFO.
*/
eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_TX_TIMEOUT,
chTimeUS2I(833 * 8));
if(evt) {
/* Force 446x out of TX state. */
Si446x_setReadyState(radio);
exit_msg = MSG_TIMEOUT;
break;
}
}
} else {
/* Transmit start failed. */
TRACE_ERROR("SI > Transmit start failed");
}
chVTReset(&send_timer);
/*
* If nothing went wrong wait for TX to finish.
* Else don't wait.
*/
while(Si446x_getState(radio) == Si446x_STATE_TX && exit_msg == MSG_OK) {
/* Sleep for an AFSK byte time. */
chThdSleep(chTimeUS2I(833 * 8));
continue;
}
if(lower > (free / 2)) {
/* Warn when level drops below 50% of FIFO size. */
TRACE_WARN("SI > AFSK TX FIFO dropped below safe threshold %i", lower);
}
// Free packet object memory
pktReleaseSendObject(pp);
/* Schedule thread memory release. */
pktScheduleThreadRelease(radio, chThdGetSelfX());
/* Exit thread. */
chThdExit(exit_msg);
}
/*
* Simple AFSK send thread using minimized buffering.
* Simple AFSK send thread with minimized buffering and en bloc send capability.
* Uses an iterator to size NRZI output and allocate suitably sized buffer.
* Plan is to replace with a version using even less memory.
*
@ -1000,28 +822,28 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
radio_unit_t radio = rto->handler->radio;
pktAcquireRadio(radio, TIME_INFINITE);
pktAcquireRadio(radio, TIME_INFINITE);
/* Initialize radio. */
Si446x_conditional_init(radio);
/* Initialize radio. */
Si446x_conditional_init(radio);
Si446x_setBandParameters(radio, rto->base_frequency,
rto->step_hz);
Si446x_setBandParameters(radio, rto->base_frequency,
rto->step_hz);
/* Set 446x back to READY. */
Si446x_pauseReceive(radio);
/* Set 446x back to READY. */
Si446x_pauseReceive(radio);
Si446x_setModemAFSK_TX(radio);
Si446x_setModemAFSK_TX(radio);
/* Initialize variables for AFSK encoder. */
virtual_timer_t send_timer;
/* Initialize variables for AFSK encoder. */
virtual_timer_t send_timer;
chVTObjectInit(&send_timer);
msg_t exit_msg = MSG_OK;
tx_iterator_t iterator;
packet_t np = NULL;
do {
chVTObjectInit(&send_timer);
msg_t exit_msg = MSG_OK;
tx_iterator_t iterator;
packet_t np = NULL;
do {
// ======================== loop here for linked packets ============
/*
* Set NRZI encoding format.
* Iterator object.
@ -1077,7 +899,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
* If the 446x gets locked up we'll exit TX and release packet object.
*/
chVTSet(&send_timer, TIME_S2I(10),
(vtfunc_t)Si446x_transmitTimeoutI, chThdGetSelfX());
(vtfunc_t)Si446x_transmitTimeoutI, chThdGetSelfX());
/* The exit message if all goes well. */
exit_msg = MSG_OK;
@ -1110,7 +932,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
/* Load the FIFO. */
for(uint16_t i = 0; i < more; i++)
//localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
//localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0);
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
c += more;
@ -1121,7 +943,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
* If no timeout event go back and load more data to FIFO.
*/
eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_TX_TIMEOUT,
chTimeUS2I(833 * 8));
chTimeUS2I(833 * 8));
if(evt) {
/* Force 446x out of TX state. */
Si446x_setReadyState(radio);
@ -1131,8 +953,8 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
}
} else {
/* Transmit start failed. */
TRACE_ERROR("SI > Transmit start failed");
exit_msg = MSG_ERROR;
TRACE_ERROR("SI > Transmit start failed");
exit_msg = MSG_ERROR;
}
chVTReset(&send_timer);
@ -1159,23 +981,19 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
/* Send was OK. Release the just completed packet. */
pktReleaseSendObject(pp);
} else {
/* Send failed so release queue and terminate. */
pktReleaseSendQueue(pp);
np = NULL;
} else {
/* Send failed so release queue and terminate. */
pktReleaseSendQueue(pp);
np = NULL;
}
// Free packet object memory
pktReleaseSendObject(pp);
} while(np != NULL);
// ======================== loop here for linked packets ============
} while(np != NULL);
/* Schedule thread memory release. */
pktSignalSendComplete(rto, chThdGetSelfX());
//pktScheduleThreadRelease(radio, chThdGetSelfX());
/* Schedule thread memory release. */
pktSignalSendComplete(rto, chThdGetSelfX());
/* Exit thread. */
chThdExit(exit_msg);
/* Exit thread. */
chThdExit(exit_msg);
}
/*
@ -1203,35 +1021,6 @@ bool Si446x_blocSendAFSK(radio_task_object_t *rt) {
return true;
}
/*
*
*/
void Si446x_sendAFSK(packet_t pp) {
thread_t *afsk_feeder_thd = NULL;
/* Create a send thread name which includes the sequence number. */
chsnprintf(pp->tx_thd_name, sizeof(pp->tx_thd_name),
"446x_afsk_tx_%03i", pp->tx_seq);
afsk_feeder_thd = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(SI_AFSK_FIFO_MIN_FEEDER_WA_SIZE),
pp->tx_thd_name,
NORMALPRIO - 10,
min_si_fifo_feeder_afsk,
pp);
if(afsk_feeder_thd == NULL) {
/* Release packet object. */
pktReleaseSendObject(pp);
TRACE_ERROR("SI > Unable to create AFSK transmit thread");
}
return;
}
/* ===================================================================== AFSK Receiver ====================================================================== */
@ -1243,161 +1032,7 @@ void Si446x_stopDecoder(void) {
/* ========================================================================== 2FSK ========================================================================== */
/*
* New 2FSK send thread using minimised buffer space.
*/
THD_FUNCTION(min_si_fifo_feeder_fsk, arg) {
packet_t pp = arg;
radio_unit_t radio = pp->radio;
/* TODO: Check result. */
pktAcquireRadio(radio, TIME_INFINITE);
// Initialize radio
Si446x_conditional_init(radio);
/* Set 446x back to READY. */
Si446x_pauseReceive(radio);
Si446x_setBandParameters(radio, pp->base_frequency, pp->radio_step);
/* Set parameters for 2FSK transmission.
* TODO: Should we pass in 9600 or just set it here?
* In any case we should have a define I guess. */
Si446x_setModem2FSK_TX(9600);
/* Initialize variables for 2FSK encoder. */
virtual_timer_t send_timer;
chVTObjectInit(&send_timer);
tx_iterator_t iterator;
pktStreamIteratorInit(&iterator, pp, 30, 10, 10, true);
/* Compute size of NRZI stream. */
uint16_t all = pktStreamEncodingIterator(&iterator, NULL, 0);
//TRACE_INFO("SI > 2FSK packet stream bytes %i", all);
if(all == 0) {
/* Nothing encoded. Release packet send object. */
TRACE_ERROR("SI > 2FSK TX no NRZI data encoded");
// Free packet object memory
pktReleaseSendObject(pp);
/* Schedule thread memory release. */
pktScheduleThreadRelease(radio, chThdGetSelfX());
/* Exit thread. */
chThdExit(MSG_RESET);
}
/* Allocate buffer and perform NRZI encoding. */
uint8_t layer0[all];
//memset(layer0, 0, sizeof(layer0));
pktStreamEncodingIterator(&iterator, layer0, all);
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
/* Get the FIFO buffer amount currently available. */
uint8_t free = Si446x_getTXfreeFIFO();
/* Calculate initial FIFO fill. */
uint16_t c = (all > free) ? free : all;
/*
* Start transmission timeout timer.
* If the 446x gets locked up we'll exit TX and release packet object.
*/
chVTSet(&send_timer, TIME_S2I(10),
(vtfunc_t)Si446x_transmitTimeoutI, chThdGetSelfX());
/* The exit message if all goes well. */
msg_t exit_msg = MSG_OK;
uint8_t *bufp = layer0;
/* Initial FIFO load. */
Si446x_writeFIFO(bufp, c);
bufp += c;
uint8_t lower = 0;
/* Request start of transmission. */
if(Si446x_transmit(radio,
pp->base_frequency,
pp->radio_step,
pp->radio_chan,
pp->radio_pwr,
all,
pp->cca_rssi,
TIME_S2I(10))) {
/* Feed the FIFO while data remains to be sent. */
while((all - c) > 0) {
/* Get TX FIFO free count. */
uint8_t more = Si446x_getTXfreeFIFO();
/* Update the FIFO free low water mark. */
lower = (more > lower) ? more : lower;
/* If there is more free than we need for send use remainder only. */
more = (more > (all - c)) ? (all - c) : more;
/* Load the FIFO. */
Si446x_writeFIFO(bufp, more); // Write into FIFO
bufp += more;
c += more;
/*
* Wait for a timeout event during up-sampled NRZI send.
* Time delay allows ~10 bytes to be consumed from FIFO.
* If no timeout event go back and load more data to FIFO.
*/
eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_TX_TIMEOUT,
chTimeUS2I(104 * 8 * 10));
if(evt) {
/* Force 446x out of TX state. */
Si446x_setReadyState(radio);
exit_msg = MSG_TIMEOUT;
break;
}
}
} else {
/* Transmit start failed. */
TRACE_ERROR("SI > 2FSK transmit start failed");
}
chVTReset(&send_timer);
/*
* If nothing went wrong wait for TX to finish.
* Else don't wait.
*/
while(Si446x_getState(radio) == Si446x_STATE_TX && exit_msg == MSG_OK) {
/* Sleep for a 2FSK byte time. */
chThdSleep(chTimeUS2I(104 * 8 * 10));
continue;
}
if(lower > (free / 2)) {
/* Warn when level drops below 50% of FIFO size. */
TRACE_WARN("SI > AFSK TX FIFO dropped below safe threshold %i", lower);
}
// Free packet object memory
pktReleaseSendObject(pp);
/* Schedule thread memory release. */
pktScheduleThreadRelease(radio, chThdGetSelfX());
/* Exit thread. */
chThdExit(exit_msg);
}
/*
* New 2FSK send thread using minimised buffer space and linked queue send.
* New 2FSK send thread using minimised buffer space and en bloc queue send.
*/
THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
radio_task_object_t *rto = arg;
@ -1594,32 +1229,6 @@ bool Si446x_blocSend2FSK(radio_task_object_t *rt) {
}
return true;
}
/*
*
*/
void Si446x_send2FSK(packet_t pp) {
thread_t *fsk_feeder_thd = NULL;
/* Create a send thread name which includes the sequence number. */
chsnprintf(pp->tx_thd_name, sizeof(pp->tx_thd_name),
"446x_2fsk_tx_%03i", pp->tx_seq);
fsk_feeder_thd = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(SI_FSK_FIFO_FEEDER_WA_SIZE),
pp->tx_thd_name,
NORMALPRIO - 10,
min_si_fifo_feeder_fsk,
pp);
if(fsk_feeder_thd == NULL) {
/* Release packet object. */
pktReleaseSendObject(pp);
TRACE_ERROR("SI > Unable to create FSK transmit thread");
}
return;
}
/* ========================================================================== Misc ========================================================================== */

Wyświetl plik

@ -267,11 +267,11 @@ static inline bool Si446x_isFrequencyInBand(radio_unit_t radio,
return (Si446x_MIN_FREQ <= freq && freq < Si446x_MAX_FREQ);
}
extern void pktReleaseOutgoingBuffer(packet_t pp);
extern void pktReleasePacketBuffer(packet_t pp);
static inline void Si446x_releaseSendObject(packet_t pp) {
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
#else
ax25_delete(pp);
#endif

Wyświetl plik

@ -125,7 +125,7 @@ bool pktServiceRelease(radio_unit_t radio) {
if(handler->state != PACKET_READY)
return false;
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktOutgoingBufferSemaphoreRelease(radio);
pktBufferSemaphoreRelease(radio);
#endif
pktRadioManagerRelease(radio);
handler->state = PACKET_IDLE;
@ -905,7 +905,7 @@ dyn_semaphore_t *pktOutgoingBufferSemaphoreCreate(radio_unit_t radio) {
* @retval MSG_TIMEOUT if the semaphore has not been signaled or reset within
* the specified timeout.
*/
msg_t pktGetOutgoingBuffer(packet_t *pp, sysinterval_t timeout) {
msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout) {
/* Check if the transmit packet buffer semaphore already exists.
* If so we get a pointer to it and just return that.
@ -940,21 +940,17 @@ msg_t pktGetOutgoingBuffer(packet_t *pp, sysinterval_t timeout) {
}
/*
* Send shares a common pool of buffers.
* @retval MSG_RESET if the semaphore has been reset using @p chSemReset().
* @retval MSG_TIMEOUT if the semaphore has not been signaled or reset within
* the specified timeout.
* A common pool of AX25 buffers.
*/
void pktReleaseOutgoingBuffer(packet_t pp) {
void pktReleasePacketBuffer(packet_t pp) {
/* Check if the transmit packet buffer semaphore already exists.
* If so we get a pointer to it and just return that.
* Otherwise create the semaphore and return result.
/* Check if the packet buffer semaphore exists.
* If not this is a system error.
*/
dyn_semaphore_t *dyn_sem =
chFactoryFindSemaphore(PKT_SEND_BUFFER_SEM_NAME);
chDbgAssert(dyn_sem != NULL, "no send PKT semaphore");
chDbgAssert(dyn_sem != NULL, "no general packet buffer semaphore");
/* Free buffer memory. */
ax25_delete(pp);
@ -969,7 +965,7 @@ void pktReleaseOutgoingBuffer(packet_t pp) {
/*
* Send shares a common pool of buffers.
*/
void pktOutgoingBufferSemaphoreRelease(radio_unit_t radio) {
void pktBufferSemaphoreRelease(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);

Wyświetl plik

@ -236,9 +236,9 @@ extern "C" {
dyn_objects_fifo_t *pktOutgoingBufferPoolCreate(radio_unit_t radio);
void pktOutgoingBufferPoolRelease(radio_unit_t radio);
dyn_semaphore_t *pktOutgoingBufferSemaphoreCreate(radio_unit_t radio);
void pktOutgoingBufferSemaphoreRelease(radio_unit_t radio);
msg_t pktGetOutgoingBuffer(packet_t *pp, sysinterval_t timeout);
void pktReleaseOutgoingBuffer(packet_t pp);
void pktBufferSemaphoreRelease(radio_unit_t radio);
msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout);
void pktReleasePacketBuffer(packet_t pp);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -381,7 +381,7 @@ static inline void pktReleaseSendObject(packet_t pp) {
#if USE_SPI_ATTACHED_RADIO == TRUE
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
@ -405,7 +405,7 @@ static inline void pktReleaseSendQueue(packet_t pp) {
/* Release all packets in linked list. */
do {
packet_t np = pp->nextp;
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
pp = np;
} while(pp != NULL);
#else

Wyświetl plik

@ -282,16 +282,13 @@ packet_t ax25_new (void) {
return NULL;
}
/*
* Note this sets the nextp link to NULL.
* If removing the memset then set nextp to NULL explicitly.
*/
memset(this_p, 0, sizeof(struct packet_s));
this_p->magic1 = MAGIC;
this_p->seq = last_seq_num;
this_p->magic2 = MAGIC;
this_p->num_addr = (-1);
this_p->nextp = NULL;
return (this_p);
}
@ -336,7 +333,6 @@ void ax25_delete (packet_t this_p)
this_p->magic1 = 0;
this_p->magic1 = 0;
//memset (this_p, 0, sizeof (struct packet_s));
chHeapFree(this_p);
}
@ -400,7 +396,7 @@ packet_t ax25_from_text (char *monitor, int strict)
#if USE_NEW_PKT_TX_ALLOC == TRUE
packet_t this_p;
msg_t msg = pktGetOutgoingBuffer(&this_p, TIME_INFINITE);
msg_t msg = pktGetPacketBuffer(&this_p, TIME_INFINITE);
/* If the semaphore is reset then exit. */
if(msg == MSG_RESET)
return NULL;
@ -454,7 +450,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if (pinfo == NULL) {
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -477,7 +473,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if (pa == NULL) {
TRACE_ERROR ("Failed to create packet from text. No source address");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -487,7 +483,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if ( ! ax25_parse_addr (AX25_SOURCE, pa, strict, atemp, &ssid_temp, &heard_temp)) {
TRACE_ERROR ("Failed to create packet from text. Bad source address");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -506,7 +502,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if (pa == NULL) {
TRACE_ERROR ("Failed to create packet from text. No destination address");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -516,7 +512,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if ( ! ax25_parse_addr (AX25_DESTINATION, pa, strict, atemp, &ssid_temp, &heard_temp)) {
TRACE_ERROR ("Failed to create packet from text. Bad destination address");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -539,7 +535,7 @@ packet_t ax25_from_text (char *monitor, int strict)
if ( ! ax25_parse_addr (k, pa, strict, atemp, &ssid_temp, &heard_temp)) {
TRACE_ERROR ("Failed to create packet from text. Bad digipeater address");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(this_p);
pktReleasePacketBuffer(this_p);
#else
ax25_delete (this_p);
#endif
@ -670,7 +666,7 @@ packet_t ax25_from_frame (unsigned char *fbuf, int flen)
}
#if USE_NEW_PKT_TX_ALLOC == TRUE
msg_t msg = pktGetOutgoingBuffer(&this_p, TIME_INFINITE);
msg_t msg = pktGetPacketBuffer(&this_p, TIME_INFINITE);
/* If the semaphore is reset then exit. */
if(msg == MSG_RESET)
return NULL;
@ -726,7 +722,7 @@ packet_t ax25_dup (packet_t copy_from)
#if USE_NEW_PKT_TX_ALLOC == TRUE
msg_t msg = pktGetOutgoingBuffer(&this_p, TIME_INFINITE);
msg_t msg = pktGetPacketBuffer(&this_p, TIME_INFINITE);
/* If the semaphore is reset then exit. */
if(msg == MSG_RESET)
return NULL;

Wyświetl plik

@ -130,22 +130,10 @@ typedef struct packet_s {
#define SSID_LAST_MASK 0x01
/*
* Pass the radio parameters and radio ID.
* This enables multiple send requests to be queued with their own data.
* TODO: Will be deprecated as TX will be passed radio object with ref to pp
*/
radio_unit_t radio;
radio_freq_t base_frequency;
channel_hz_t radio_step;
radio_ch_t radio_chan;
radio_pwr_t radio_pwr;
radio_squelch_t cca_rssi;
uint16_t preamble_size;
//===========================
/* The transmit sequence number for this packet. */
uint8_t tx_seq;
/* TODO: Set size of name with definition. */
/* TODO: Move this out of here... */
char tx_thd_name[16];
/* Frame length without CRC. */
@ -363,8 +351,8 @@ extern packet_t ax25_dup (packet_t copy_from);
extern void ax25_delete (packet_t pp);
extern msg_t pktGetOutgoingBuffer(packet_t *pp, sysinterval_t timeout);
extern void pktReleaseOutgoingBuffer(packet_t pp);
extern msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout);
extern void pktReleasePacketBuffer(packet_t pp);
#endif

Wyświetl plik

@ -540,8 +540,10 @@ static bool aprs_decode_message(packet_t pp)
return true; // Mark that message has to be digipeated
}
static void aprs_digipeat(packet_t pp)
{
/*
* Transmit failure will release the packet memory.
*/
static void aprs_digipeat(packet_t pp) {
if(!dedupe_initialized) {
dedupe_init(TIME_S2I(10));
dedupe_initialized = true;
@ -580,50 +582,52 @@ packet_t aprs_encode_telemetry_configuration(const char *callsign,
}
}
void aprs_decode_packet(packet_t pp)
{
// Get heard callsign
char call[AX25_MAX_ADDR_LEN];
int8_t v = -1;
do {
v++;
ax25_get_addr_with_ssid(pp, ax25_get_heard(pp)-v, call);
} while(ax25_get_heard(pp)-v >= AX25_SOURCE && (!strncmp("WIDE", call, 4) || !strncmp("TRACE", call, 5)));
/*
*
*/
void aprs_decode_packet(packet_t pp) {
// Get heard callsign
char call[AX25_MAX_ADDR_LEN];
int8_t v = -1;
do {
v++;
ax25_get_addr_with_ssid(pp, ax25_get_heard(pp)-v, call);
} while(ax25_get_heard(pp)-v >= AX25_SOURCE && (!strncmp("WIDE", call, 4) || !strncmp("TRACE", call, 5)));
// Fill/Update direct list
sysinterval_t first_time = 0xFFFFFFFF; // Timestamp of oldest heard list entry
uint8_t first_id = 0; // ID of oldest heard list entry
// Fill/Update direct list
sysinterval_t first_time = 0xFFFFFFFF; // Timestamp of oldest heard list entry
uint8_t first_id = 0; // ID of oldest heard list entry
for(uint8_t i=0; i<=20; i++) {
if(i < 20) {
// Search for callsign in list
if(!strcmp(heard_list[i].call, call)) { // Callsign found in list
heard_list[i].time = chVTGetSystemTime(); // Update time the callsign was last heard
break;
}
for(uint8_t i=0; i<=20; i++) {
if(i < 20) {
// Search for callsign in list
if(!strcmp(heard_list[i].call, call)) { // Callsign found in list
heard_list[i].time = chVTGetSystemTime(); // Update time the callsign was last heard
break;
}
// Find oldest entry
if(first_time > heard_list[i].time) {
first_time = heard_list[i].time;
first_id = i;
}
} else { // Callsign not in list
// Overwrite old entry/ use empty entry
memcpy(heard_list[first_id].call, call, sizeof(heard_list[first_id].call));
heard_list[first_id].time = chVTGetSystemTime();
}
}
// Find oldest entry
if(first_time > heard_list[i].time) {
first_time = heard_list[i].time;
first_id = i;
}
} else { // Callsign not in list
// Overwrite old entry/ use empty entry
memcpy(heard_list[first_id].call, call, sizeof(heard_list[first_id].call));
heard_list[first_id].time = chVTGetSystemTime();
}
}
// Decode message packets
bool digipeat = true;
unsigned char *pinfo;
if(ax25_get_info(pp, &pinfo) == 0)
return;
if(pinfo[0] == ':') digipeat = aprs_decode_message(pp); // ax25_get_dti(pp)
// Decode message packets
bool digipeat = true;
unsigned char *pinfo;
if(ax25_get_info(pp, &pinfo) == 0)
return;
if(pinfo[0] == ':') digipeat = aprs_decode_message(pp); // ax25_get_dti(pp)
// Digipeat packet
if(conf_sram.aprs.dig_active && digipeat) {
aprs_digipeat(pp);
}
// Digipeat packet
if(conf_sram.aprs.dig_active && digipeat) {
aprs_digipeat(pp);
}
}

Wyświetl plik

@ -9,44 +9,51 @@
#include "radio.h"
static void processPacket(uint8_t *buf, uint32_t len) {
/* Remove CRC from frame. */
if(len > 2) {
len -= 2;
// Decode APRS frame
packet_t pp = ax25_from_frame(buf, len);
if(pp != NULL) {
uint8_t *c;
uint32_t len = ax25_get_info(pp, &c);
if(len == 0) {
TRACE_INFO("RX > Invalid packet structure - dropped");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
#else
ax25_delete (pp);
#endif
return;
}
char serial_buf[512];
aprs_debug_getPacket(pp, serial_buf, sizeof(serial_buf));
TRACE_INFO("RX > %s", serial_buf);
if(pp->num_addr > 0) {
aprs_decode_packet(pp);
} else {
TRACE_INFO("RX > No addresses in packet - dropped");
}
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
#else
ax25_delete (pp);
#endif
} else {
TRACE_INFO("RX > Error in packet - dropped");
}
return;
if(len < 3) {
/*
* Incoming packet was too short.
* Don't yet have a general packet so nothing to do.
*/
TRACE_INFO("RX > Packet dropped due to data length < 2");
return;
}
TRACE_INFO("RX > Packet dropped due to data length < 2");
/* Remove CRC from frame. */
len -= 2;
/* Decode APRS frame. */
packet_t pp = ax25_from_frame(buf, len);
if(pp == NULL) {
TRACE_INFO("RX > Error in packet - dropped");
return;
}
/* Continue packet analysis. */
uint8_t *c;
uint32_t ilen = ax25_get_info(pp, &c);
if(ilen == 0) {
TRACE_INFO("RX > Invalid packet structure - dropped");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
return;
}
/* Output packet as text. */
char serial_buf[512];
aprs_debug_getPacket(pp, serial_buf, sizeof(serial_buf));
TRACE_INFO("RX > %s", serial_buf);
if(pp->num_addr > 0)
aprs_decode_packet(pp);
else
TRACE_INFO("RX > No addresses in packet - dropped");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
}
void mapCallback(pkt_data_object_t *pkt_buff) {
@ -118,7 +125,7 @@ bool transmitOnRadio(packet_t pp, radio_freq_t base_freq,
if(!pktIsTransmitOpen(radio)) {
TRACE_WARN( "RAD > Transmit is not open on radio");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
@ -151,6 +158,11 @@ bool transmitOnRadio(packet_t pp, radio_freq_t base_freq,
TRACE_ERROR("RAD > Transmit base frequency of %d.%03d MHz is invalid",
base_freq/1000000, (base_freq%1000000)/1000);
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
return false;
}
@ -191,7 +203,7 @@ bool transmitOnRadio(packet_t pp, radio_freq_t base_freq,
if(msg != MSG_OK) {
TRACE_ERROR("RAD > Failed to post radio task");
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
@ -204,7 +216,7 @@ bool transmitOnRadio(packet_t pp, radio_freq_t base_freq,
base_freq/1000000, (base_freq%1000000)/1000, pwr,
getModulation(mod), len);
#if USE_NEW_PKT_TX_ALLOC == TRUE
pktReleaseOutgoingBuffer(pp);
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif