o.w.varley
Well-known member
Hey all,
I'm trying to pin point an issue I've got that's causing the Teensy to crash. I've probably got too much code to share in full, however, I'll attempt to explain what I'm doing and that might help pin-point where the issue is. I'm building a program that allows audio to be transmitted and received via UDP. An AudioController class is defined with three 4 channel mixers, two take 8 inputs and combine them all into a single output to an I2C, the class definition for this with the Audio component definitions is below:
The AudioController reads UDP Packets and, when it finds packets that relate to audio data it enqueues these within buffers in the AudioVoiceIn objects it contains. From what I'm testing, the issue looks to be in the ReadUDP function, this checks the first byte of the UDP packet and if its an audio packet it calls ReadAudioPAcketFromUDP code for this below:
The AudioVoiceIn class contains within it a buffer into which audio blocks are enqueued. The memory for these blocks is allocated within the function above, as you can see I'm clearing the memory allocated to the packet in any of the cases that enqueue isn't called. Within the AudioVoiceIn class the Update function is responsible for releasing the memory allocated to packet. This is done within the Update function which is shown below:
For _buffer I was initially using an std::queue, however, as I thought this might be the issue I swapped recently across to using TonTon's Circular Buffer but the problem remains. I've tried wrapping the Enqueue call with disabling/enabling interrupts but this doesn't make any difference either. I've got a bunch of crash reports, however, when using addr2line I get ??:?, Crash Reports are below:
In terms of diagnostic data, I'm monitoring RAM2, Audio Memory, CPU usage levels every second and none of these seem to be an issue. RAM2 reports around 300k free, Audio memory max is about 9 (With 64 blocks allocated as its max) and the CPU never gets above 2.0.
Any top tips on how to debug issues like this would be really appreciated. Even just being able to hone in on the suspect line of code would be a start as its frustrating that addr2line doesn't work!
Thanks,
Owen
I'm trying to pin point an issue I've got that's causing the Teensy to crash. I've probably got too much code to share in full, however, I'll attempt to explain what I'm doing and that might help pin-point where the issue is. I'm building a program that allows audio to be transmitted and received via UDP. An AudioController class is defined with three 4 channel mixers, two take 8 inputs and combine them all into a single output to an I2C, the class definition for this with the Audio component definitions is below:
Code:
#pragma once
#include <SPI.h>
#include <Audio.h>
#include <Wire.h>
#include <SerialFlash.h>
#include <list>
#include "Constants.h"
#include "AudioVoiceOut.h"
#include "AudioVoiceIn.h"
class AudioController
{
const int DEFAULT_GAIN = 40;
static const int NUM_INPUT_CHANNELS = 8;
const int INTERCOM_MIX_CHANNEL = 0;
const int MIC_MIX_CHANNEL = 1;
const int VUHF1_MIX_CHANNEL = 2;
const int VUHF2_MIX_CHANNEL = 3;
const int TAC1_MIX_CHANNEL = 0;
const int TAC2_MIX_CHANNEL = 1;
const int DAS_MIX_CHANNEL = 2;
const int AIRCRAFT_MIX_CHANNEL = 3;
public:
AudioController() : _channelOut(PORT, PACKET_INTERCOM),
_patchCord1(_intercomIn, 0, _preMix1, INTERCOM_MIX_CHANNEL),
_patchCord2(_mic, 0, _preMix1, MIC_MIX_CHANNEL),
_patchCord3(_VUHF1, 0, _preMix1, VUHF1_MIX_CHANNEL),
_patchCord4(_VUHF2, 0, _preMix1, VUHF2_MIX_CHANNEL),
_patchCord5(_TAC1, 0, _preMix1, TAC1_MIX_CHANNEL),
_patchCord6(_TAC2, 0, _preMix2, TAC2_MIX_CHANNEL),
_patchCord7(_DAS, 0, _preMix2, DAS_MIX_CHANNEL),
_patchCord8(_Aircraft, 0, _preMix2, AIRCRAFT_MIX_CHANNEL),
_patchCord9(_mic, 0, _channelOut, 0),
_patchCord10(_preMix1, 0, _finalMix, 0),
_patchCord11(_preMix2, 0, _finalMix, 1),
_patchCord12(_finalMix, 0, _headset, 0),
_patchCord13(_finalMix, 0, _headset, 1)
{
const float VOLUME = 0.65;
AudioMemory(64);
_sgtl5000.enable();
_sgtl5000.volume(VOLUME);
_sgtl5000.inputSelect(AUDIO_INPUT_MIC);
_sgtl5000.micGain(DEFAULT_GAIN);
delay(1000);
InitChannels();
Serial.println("Audio setup complete");
}
void AdjustVolume(uint8_t packetType, uint8_t volume);
void Begin(bool isSimA);
std::list<uint16_t> GetBufferSizes();
AudioVoiceOut* GetVoiceOut() { return &_channelOut; }
void ReadUDP();
void StartTransmitting(uint8_t packetType);
void StopTransmitting();
private:
void InitChannels();
void ReadAudioPacketFromUDP();
void ReadChannelChangePacketFromUDP();
AudioInputI2S _mic;
AudioVoiceIn _intercomIn;
AudioVoiceIn _VUHF1;
AudioVoiceIn _VUHF2;
AudioVoiceIn _TAC1;
AudioVoiceIn _TAC2;
AudioVoiceIn _DAS;
AudioVoiceIn _Aircraft;
AudioMixer4 _preMix1;
AudioMixer4 _preMix2;
AudioMixer4 _finalMix;
AudioVoiceOut _channelOut;
AudioOutputI2S _headset;
AudioConnection _patchCord1;
AudioConnection _patchCord2;
AudioConnection _patchCord3;
AudioConnection _patchCord4;
AudioConnection _patchCord5;
AudioConnection _patchCord6;
AudioConnection _patchCord7;
AudioConnection _patchCord8;
AudioConnection _patchCord9;
AudioConnection _patchCord10;
AudioConnection _patchCord11;
AudioConnection _patchCord12;
AudioConnection _patchCord13;
AudioControlSGTL5000 _sgtl5000;
uint32_t _intercomChannel;
EthernetUDP _client;
AudioVoiceIn* _channels[NUM_INPUT_CHANNELS];
};
The AudioController reads UDP Packets and, when it finds packets that relate to audio data it enqueues these within buffers in the AudioVoiceIn objects it contains. From what I'm testing, the issue looks to be in the ReadUDP function, this checks the first byte of the UDP packet and if its an audio packet it calls ReadAudioPAcketFromUDP code for this below:
Code:
void AudioController::ReadAudioPacketFromUDP()
{
uint8_t packetType = PACKET_NONE;
uint32_t channelId;
int16_t* packet = new int16_t[AUDIO_BLOCK_SAMPLES];
// Packet format for Audio
// Header - Byte
// Packet Type - Byte
// ChannelID - 4 Bytes (Unsigned Int32)
// Packet Data - 256 Bytes
_client.read((uint8_t*)&packetType, sizeof(packetType));
_client.read((uint8_t*)&channelId, sizeof(channelId));
_client.read((uint8_t*)packet, AUDIO_BLOCK_SAMPLES * 2);
if (packetType < PACKET_MIN || packetType > PACKET_MAX)
{
Serial.printf("Invalid packetType (%d) ignoring packet.\n", packetType);
delete[] packet;
packet = NULL;
return;
}
AudioVoiceIn* channel = _channels[packetType];
// Special handling is included here for the GOD channel. This will allow an instructor to transmit on a single channel
// and be received by both SIM A and SIM B.
if (channel->GetChannel() == channelId || channelId == CHANNEL_INTERCOM_GOD)
{
channel->Enqueue(packet);
}
else
{
delete[] packet;
packet = NULL;
}
}
The AudioVoiceIn class contains within it a buffer into which audio blocks are enqueued. The memory for these blocks is allocated within the function above, as you can see I'm clearing the memory allocated to the packet in any of the cases that enqueue isn't called. Within the AudioVoiceIn class the Update function is responsible for releasing the memory allocated to packet. This is done within the Update function which is shown below:
Code:
void AudioVoiceIn::update(void)
{
audio_block_t* block;
// only update if we're playing
if (!_enabled) return;
// don't update or allocate memory if there is nothing to play
if (_buffer.size() <= 0) return;
// allocate the audio blocks to transmit
block = allocate();
if (block == NULL) return;
if (_buffer.size() > 0)
{
int16_t* packet = _buffer.pop_front();
memcpy(block->data, packet, sizeof(block->data));
transmit(block);
delete[] packet;
packet = NULL;
}
release(block);
}
For _buffer I was initially using an std::queue, however, as I thought this might be the issue I swapped recently across to using TonTon's Circular Buffer but the problem remains. I've tried wrapping the Enqueue call with disabling/enabling interrupts but this doesn't make any difference either. I've got a bunch of crash reports, however, when using addr2line I get ??:?, Crash Reports are below:
Code:
CrashReport:
A problem occurred at (system time) 10:33:43
Code was executing from address 0x42D94
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0x9400A2
Temperature inside the chip was 65.00 °C
Startup CPU clock speed is 600MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
CrashReport:
A problem occurred at (system time) 10:36:50
Code was executing from address 0x42D94
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0xFFFEFFF0
Temperature inside the chip was 65.77 °C
Startup CPU clock speed is 600MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
A problem occurred at (system time) 10:41:35
Code was executing from address 0x42DE0
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0xFFF4FFFB
Temperature inside the chip was 65.00 °C
Startup CPU clock speed is 600MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
In terms of diagnostic data, I'm monitoring RAM2, Audio Memory, CPU usage levels every second and none of these seem to be an issue. RAM2 reports around 300k free, Audio memory max is about 9 (With 64 blocks allocated as its max) and the CPU never gets above 2.0.
Any top tips on how to debug issues like this would be really appreciated. Even just being able to hone in on the suspect line of code would be a start as its frustrating that addr2line doesn't work!
Thanks,
Owen