AP_HAL_Linux: fixed signal handler in RCInput_Navio

DMA is getting stopped in the separate method now. This is the best we
can get at the current time. It does yield slightly better experience
and works in the majority of cases.

The patch is a no bulletproof solution, though.

There's a possibility of corruption in case of e.g. a SIGKILL. There's
no signal framework at the time and the commit doesn't add one. That's
why all signals are handled in the same erroneous way. This is not a
good nor a final solution to the issue.

For the issue at hand a better fix might be porting the code to kernel
space but it's a rather tediuos task that we cannot undertake in the
couple of weeks.
This commit is contained in:
Staroselskii Georgii 2015-07-09 17:07:53 +03:00 committed by Andrew Tridgell
parent 8528a7d159
commit d7ac725a64
2 changed files with 13 additions and 7 deletions

View File

@ -264,11 +264,16 @@ void LinuxRCInput_Navio::init_dma_cb(dma_cb_t** cbp, uint32_t mode, uint32_t sou
(*cbp)->stride = stride;
}
//Non-stoping DMA when the process is finished will lead to crash
void LinuxRCInput_Navio::stop_dma_and_exit(int param)
void LinuxRCInput_Navio::stop_dma()
{
dma_reg[RCIN_NAVIO_DMA_CS | RCIN_NAVIO_DMA_CHANNEL << 8] = 0; // stop dma
exit(1);
dma_reg[RCIN_NAVIO_DMA_CS | RCIN_NAVIO_DMA_CHANNEL << 8] = 0;
}
/* We need to be sure that the DMA is stopped upon termination */
void LinuxRCInput_Navio::termination_handler(int signum)
{
stop_dma();
hal.scheduler->panic("Interrupted");
}
@ -380,7 +385,7 @@ void LinuxRCInput_Navio::set_sigaction()
//catch all signals (like ctrl+c, ctrl+z, ...) to ensure DMA is disabled
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = LinuxRCInput_Navio::stop_dma_and_exit;
sa.sa_handler = LinuxRCInput_Navio::termination_handler;
sigaction(i, &sa, NULL);
}
}
@ -413,7 +418,7 @@ LinuxRCInput_Navio::~LinuxRCInput_Navio()
void LinuxRCInput_Navio::deinit()
{
stop_dma_and_exit(0);
stop_dma();
}
//Initializing necessary registers

View File

@ -123,7 +123,8 @@ private:
void init_PCM();
void init_DMA();
void init_buffer();
static void stop_dma_and_exit(int param);
static void stop_dma();
static void termination_handler(int signum);
void set_sigaction();
void set_physical_addresses(int version);
void deinit() override;