mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-09 01:18:29 -04:00
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:
parent
8528a7d159
commit
d7ac725a64
@ -264,11 +264,16 @@ void LinuxRCInput_Navio::init_dma_cb(dma_cb_t** cbp, uint32_t mode, uint32_t sou
|
|||||||
(*cbp)->stride = stride;
|
(*cbp)->stride = stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Non-stoping DMA when the process is finished will lead to crash
|
void LinuxRCInput_Navio::stop_dma()
|
||||||
void LinuxRCInput_Navio::stop_dma_and_exit(int param)
|
|
||||||
{
|
{
|
||||||
dma_reg[RCIN_NAVIO_DMA_CS | RCIN_NAVIO_DMA_CHANNEL << 8] = 0; // stop dma
|
dma_reg[RCIN_NAVIO_DMA_CS | RCIN_NAVIO_DMA_CHANNEL << 8] = 0;
|
||||||
exit(1);
|
}
|
||||||
|
|
||||||
|
/* 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
|
//catch all signals (like ctrl+c, ctrl+z, ...) to ensure DMA is disabled
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
memset(&sa, 0, sizeof(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);
|
sigaction(i, &sa, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +418,7 @@ LinuxRCInput_Navio::~LinuxRCInput_Navio()
|
|||||||
|
|
||||||
void LinuxRCInput_Navio::deinit()
|
void LinuxRCInput_Navio::deinit()
|
||||||
{
|
{
|
||||||
stop_dma_and_exit(0);
|
stop_dma();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Initializing necessary registers
|
//Initializing necessary registers
|
||||||
|
@ -123,7 +123,8 @@ private:
|
|||||||
void init_PCM();
|
void init_PCM();
|
||||||
void init_DMA();
|
void init_DMA();
|
||||||
void init_buffer();
|
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_sigaction();
|
||||||
void set_physical_addresses(int version);
|
void set_physical_addresses(int version);
|
||||||
void deinit() override;
|
void deinit() override;
|
||||||
|
Loading…
Reference in New Issue
Block a user