Я недавно был на собеседовании в компании, и меня спросили следующее:
Напишите функцию инициализации для счетчика сброса, который может вызываться несколькими абонентами.
Требование: вам нужноиспользовать тот же ISR для обслуживания прерывания счетчика
. Мой подход к этому заключался в использовании массива указателей на функции, который будет содержать различные функции обратного вызова для разных вызывающих, которые будут выполняться в ISR.Внутри ISR будет выбран правильный обратный вызов в зависимости от битового массива, установленного вызывающими.
// bit array positions
typedef enum // the bit number to be set by each caller
{
counter1,
counter2,
counter3,
.
.
} counter_type
// callbacks
void (*fun_ptr_arr[])(void) = // to hold the callbacks
{
callback1,
callback2,
.
.
.
}
/**
* counter initializer can pass in the callbacks and the count from which to
* downcount
*/
void initialize_counter(counter_type type, int count, void (*callback)(void))
{
bit_array |= (1 << type);
// set the counter and start downcounting
}
// ISR
void interrupt_handler(void)
{
switch(bit_array)
{
case (bit_array & (1 << counter1)):
fun_ptr_arr[counter1];
break;
.
.
.
default:
break;
}
}
Но в этом подходе отсутствуют некоторые вещи, такие как:
- Когдаогонь прерывания?
- Как значение счетчика для других абонентов сохраняется где-то и сохраняется (возможно, какая-то структура данных? интервьюер намекнул на это и также намекнул, что я могу каким-то образом использовать текущее время)
- как счетчик продолжает работать для других вызывающих абонентов после обслуживания прерывания?
Я предположил, что вызывающие абоненты могут выполнять несколько задач, и подтвердил интервьюером.
Любые идеи действительно приветствуются.