1.优化定时器允许模式.

This commit is contained in:
MacRsh
2023-06-18 22:47:45 +08:00
parent e204cc760a
commit 3dbe19a4af
2 changed files with 35 additions and 41 deletions

View File

@@ -26,7 +26,7 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
count = 1;
}
if (count < timer->information.max_cut)
if (count < timer->info.max_cnt)
{
timer->reload = 1;
timer->cycles = timer->reload;
@@ -34,16 +34,16 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
return count;
}
if (count % timer->information.max_cut == 0)
if (count % timer->info.max_cnt == 0)
{
timer->reload = count / timer->information.max_cut;
timer->reload = count / timer->info.max_cnt;
timer->cycles = timer->reload;
timer->timeout = timer->information.max_cut * timer_period;
return timer->information.max_cut;
timer->timeout = timer->info.max_cnt * timer_period;
return timer->info.max_cnt;
}
/* Calculate the Least error reload */
reload_min = count / timer->information.max_cut + 1;
reload_min = count / timer->info.max_cnt + 1;
reload_max = count / 5;
error_min = reload_min;
for (i = reload_min; i < reload_max; i++)
@@ -54,8 +54,7 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
{
reload_best = i;
break;
}
else if (error < error_min)
} else if (error < error_min)
{
error_min = error;
reload_best = i;
@@ -74,15 +73,14 @@ static mr_err_t mr_timer_open(mr_device_t device)
mr_timer_t timer = (mr_timer_t)device;
struct mr_timer_config config = MR_TIMER_CONFIG_DEFAULT;
/* Setting timer to default config, if the frequency not set */
if (timer->config.freq == 0)
{
timer->config = config;
}
if (timer->config.freq > timer->information.max_freq)
{
return -MR_ERR_GENERIC;
}
/* Check the frequency */
mr_limit(timer->config.freq, timer->info.min_freq, timer->info.max_freq);
return timer->ops->configure(timer, &timer->config);
}
@@ -91,7 +89,7 @@ static mr_err_t mr_timer_close(mr_device_t device)
{
mr_timer_t timer = (mr_timer_t)device;
/* Setting timer to close-config */
/* Setting timer to close config */
timer->config.freq = 0;
return timer->ops->configure(timer, &timer->config);
@@ -101,6 +99,7 @@ static mr_err_t mr_timer_ioctl(mr_device_t device, int cmd, void *args)
{
mr_timer_t timer = (mr_timer_t)device;
mr_err_t ret = MR_ERR_OK;
struct mr_timer_config *config = (struct mr_timer_config *)args;
switch (cmd & _MR_CTRL_FLAG_MASK)
{
@@ -109,10 +108,7 @@ static mr_err_t mr_timer_ioctl(mr_device_t device, int cmd, void *args)
if (args)
{
/* Check the frequency */
if (((struct mr_timer_config *)args)->freq > timer->information.max_freq)
{
return -MR_ERR_GENERIC;
}
mr_limit(config->freq, timer->info.min_freq, timer->info.max_freq);
ret = timer->ops->configure(timer, (struct mr_timer_config *)args);
if (ret == MR_ERR_OK)
@@ -148,20 +144,21 @@ static mr_ssize_t mr_timer_read(mr_device_t device, mr_off_t pos, void *buffer,
{
mr_timer_t timer = (mr_timer_t)device;
mr_uint32_t *recv_buffer = (mr_uint32_t *)buffer;
mr_uint32_t cut = 0;
mr_uint32_t cnt = 0;
if (size < sizeof(*recv_buffer))
{
return -MR_ERR_INVALID;
}
cut = timer->ops->get_count(timer);
if (timer->information.cut_mode == _MR_TIMER_CUT_MODE_DOWN)
/* Get the count */
cnt = timer->ops->get_count(timer);
if (timer->info.cnt_mode == _MR_TIMER_CNT_MODE_DOWN)
{
cut = timer->timeout / (1000000 / timer->config.freq) - cut;
cnt = timer->timeout / (1000000 / timer->config.freq) - cnt;
}
*recv_buffer = timer->overflow * timer->timeout + cut * (1000000 / timer->config.freq);
*recv_buffer = timer->overflow * timer->timeout + cnt * (1000000 / timer->config.freq);
return sizeof(*recv_buffer);
}
@@ -177,11 +174,6 @@ static mr_ssize_t mr_timer_write(mr_device_t device, mr_off_t pos, const void *b
return -MR_ERR_INVALID;
}
if (timer->config.freq == 0)
{
return -MR_ERR_GENERIC;
}
timer->ops->stop(timer);
timer->overflow = 0;
period_reload = mr_timer_timeout_calculate(timer, *send_buffer);
@@ -189,8 +181,9 @@ static mr_ssize_t mr_timer_write(mr_device_t device, mr_off_t pos, const void *b
/* When the time is not less than one time, the timer is started */
if (timer->cycles != 0)
{
timer->ops->start(timer, period_reload);
return -MR_ERR_INVALID;
}
timer->ops->start(timer, period_reload);
return sizeof(*send_buffer);
}
@@ -240,7 +233,8 @@ mr_err_t mr_timer_device_add(mr_timer_t timer,
MR_ASSERT(ops != MR_NULL);
MR_ASSERT(info != MR_NULL);
MR_ASSERT(info->max_freq != 0);
MR_ASSERT(info->max_cut != 0);
MR_ASSERT(info->min_freq != 0);
MR_ASSERT(info->max_cnt != 0);
/* Add the timer-device to the container */
ret = mr_device_add(&timer->device, name, MR_DEVICE_TYPE_TIMER, MR_OPEN_RDWR, &device_ops, data);
@@ -251,7 +245,7 @@ mr_err_t mr_timer_device_add(mr_timer_t timer,
/* Initialize the timer fields */
timer->config.freq = 0;
timer->information = *info;
timer->info = *info;
timer->reload = 0;
timer->cycles = 0;
timer->overflow = 0;
@@ -277,11 +271,6 @@ void mr_timer_device_isr(mr_timer_t timer, mr_uint16_t event)
{
timer->overflow++;
if (timer->cycles != 0)
{
timer->cycles--;
}
/* Timeout */
if (timer->cycles == 0)
{
@@ -299,6 +288,10 @@ void mr_timer_device_isr(mr_timer_t timer, mr_uint16_t event)
timer->device.rx_cb(&timer->device, MR_NULL);
}
}
else
{
timer->cycles--;
}
}
default:

View File

@@ -18,8 +18,8 @@
#define MR_TIMER_MODE_PERIOD 0
#define MR_TIMER_MODE_ONE_SHOT 1
#define _MR_TIMER_CUT_MODE_UP 0
#define _MR_TIMER_CUT_MODE_DOWN 1
#define _MR_TIMER_CNT_MODE_UP 0
#define _MR_TIMER_CNT_MODE_DOWN 1
#define MR_TIMER_EVENT_PIT_INT 0x1000
#define _MR_TIMER_EVENT_MASK 0xf000
@@ -27,7 +27,7 @@
/* Default config for mr_timer_config structure */
#define MR_TIMER_CONFIG_DEFAULT \
{ \
1000, \
1000000, \
MR_TIMER_MODE_PERIOD, \
}
@@ -40,8 +40,9 @@ struct mr_timer_config
struct mr_timer_info
{
mr_uint32_t max_freq;
mr_uint32_t max_cut;
mr_uint8_t cut_mode;
mr_uint32_t min_freq;
mr_uint32_t max_cnt;
mr_uint8_t cnt_mode;
};
typedef struct mr_timer *mr_timer_t;
@@ -59,7 +60,7 @@ struct mr_timer
struct mr_device device;
struct mr_timer_config config;
struct mr_timer_info information;
struct mr_timer_info info;
mr_uint32_t reload;
mr_uint32_t cycles;
mr_uint32_t overflow;