[Linux]学习笔记系列 -- [arm][lib]

文章目录

  • arch/arm/lib/delay.c
    • [register_current_timer_delay 注册当前定时器延迟](#register_current_timer_delay 注册当前定时器延迟)
    • [read_current_timer 读取当前定时器](#read_current_timer 读取当前定时器)
  • drivers/clocksource/timer-stm32.c
    • [stm32_clocksource_init STM32 平台上初始化时钟源](#stm32_clocksource_init STM32 平台上初始化时钟源)

https://github.com/wdfk-prog/linux-study

arch/arm/lib/delay.c

register_current_timer_delay 注册当前定时器延迟

c 复制代码
void __init register_current_timer_delay(const struct delay_timer *timer)
{
	u32 new_mult, new_shift;
	u64 res;

	clocks_calc_mult_shift(&new_mult, &new_shift, timer->freq,
			       NSEC_PER_SEC, 3600);
	res = cyc_to_ns(1ULL, new_mult, new_shift);

	if (res > 1000) {
		pr_err("Ignoring delay timer %ps, which has insufficient resolution of %lluns\n",
			timer, res);
		return;
	}

	if (!delay_calibrated && (!delay_res || (res < delay_res))) {
		pr_info("Switching to timer-based delay loop, resolution %lluns\n", res);
		delay_timer			= timer;
		lpj_fine			= timer->freq / HZ;
		delay_res			= res;

		/* cpufreq 可能会loops_per_jiffy扩展,因此请保留一个私有副本 */
		arm_delay_ops.ticks_per_jiffy	= lpj_fine;
		arm_delay_ops.delay		= __timer_delay;
		arm_delay_ops.const_udelay	= __timer_const_udelay;
		arm_delay_ops.udelay		= __timer_udelay;
	} else {
		pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
	}
}

read_current_timer 读取当前定时器

c 复制代码
int read_current_timer(unsigned long *timer_val)
{
	if (!delay_timer)
		return -ENXIO;

	*timer_val = delay_timer->read_current_timer();
	return 0;
}
EXPORT_SYMBOL_GPL(read_current_timer);

drivers/clocksource/timer-stm32.c

stm32_clocksource_init STM32 平台上初始化时钟源

c 复制代码
static unsigned long stm32_read_delay(void)
{
	return readl_relaxed(stm32_timer_cnt);
}

static int __init stm32_clocksource_init(struct timer_of *to)
{
	u32 bits = stm32_timer_of_bits_get(to);
	const char *name = to->np->full_name;

	/*
	 * 此驱动程序允许注册多个计时器,并依赖于通用时间框架来选择正确的计时器。
	 * 但是,不允许对 sched_clock 执行相同的作。
	 * 我们对 16 位定时器的 sched_clock 不感兴趣,而只对 32 位定时器感兴趣,
	 * 因此如果尚未注册 32 位定时器,我们选择这个 32 位定时器作为sched_clock。
	 */
	if (bits == 32 && !stm32_timer_cnt) {

		/*
		 * 立即启动计数器,因为我们将在之后立即使用它。
		 */
		stm32_timer_start(to);
		/* 获取计数器寄存器地址 */
		stm32_timer_cnt = timer_of_base(to) + TIM_CNT;
		sched_clock_register(stm32_read_sched_clock, bits, timer_of_rate(to));
		pr_info("%s: STM32 sched_clock registered\n", name);

		stm32_timer_delay.read_current_timer = stm32_read_delay;
		stm32_timer_delay.freq = timer_of_rate(to);
		register_current_timer_delay(&stm32_timer_delay);
		pr_info("%s: STM32 delay timer registered\n", name);
	}

	return clocksource_mmio_init(timer_of_base(to) + TIM_CNT, name,
				     timer_of_rate(to), bits == 32 ? 250 : 100,
				     bits, clocksource_mmio_readl_up);
}
相关推荐
Thera7773 分钟前
【Linux C++】彻底解决僵尸进程:waitpid(WNOHANG) 与 SA_NOCLDWAIT
linux·服务器·c++
阿梦Anmory8 分钟前
Ubuntu配置代理最详细教程
linux·运维·ubuntu
傻小胖12 分钟前
22.ETH-智能合约-北大肖臻老师客堂笔记
笔记·区块链·智能合约
1024小神12 分钟前
SVG标签中path路径参数学习
学习
呉師傅22 分钟前
【使用技巧】Adobe Photoshop 2024调整缩放与布局125%后出现点菜单项漂移问题的简单处理
运维·服务器·windows·adobe·电脑·photoshop
云姜.23 分钟前
线程和进程的关系
java·linux·jvm
heartbeat..25 分钟前
JVM 性能调优流程实战:从开发规范到生产应急排查
java·运维·jvm·性能优化·设计规范
浅念-28 分钟前
C++入门(2)
开发语言·c++·经验分享·笔记·学习
ZH154558913128 分钟前
Flutter for OpenHarmony Python学习助手实战:面向对象编程实战的实现
python·学习·flutter
简佐义的博客1 小时前
生信入门进阶指南:学习顶级实验室多组学整合方案,构建肾脏细胞空间分子图谱
人工智能·学习