arm linux clock implement

本文介绍了在移植新版内核过程中遇到的时钟管理问题及解决方案。针对缺少时钟管理代码的情况,通过参考其他板子的内核代码和数据手册,实现了时钟使能、禁用和获取频率等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

随性写的,不够完整,暂时先记着,还有一些没搞清楚呢!~

 

近日在做新版内核的移植工作,将原来的BSP弄进最新内核2.6.31-rc7中(已经又出新的了)。

 

在改写系统定时器(sys_timer)部分时,发现总缺少什么东西,我也不知道少什么,老大的提议+参考大牛的代码,发现这个BSP竟然没有clock管理的代码,不过也对,他们是本着能跑的理念来完成这个BSP,没有用到的就省略了,也不能怪他们。那我们就得自己实现咯!硬件、时钟对我来说还是比较吃力的,原理至今还不太清楚,参看了几块板子的内核代码和datasheet,发现时钟这些,起码在名字上是基本同一的,原来我还以为每个板子自己瞎定的。

 

时钟管理,主要的功能是使能某个时钟,因为一个时钟源通过PLL出来的频率,再加上divisor处理,就能达到可编程的时钟频率,每个硬件模块都可以有自己的频率,每个硬件模块都可以单独开关时钟。所以需要管理,因为多嘛!

 

我们的板子主要涉及到的时钟有:

PLL:时钟源出来时钟,这里可以理解为xtal时钟源;

    PLL_CPU:为其他硬件模块提供时钟的时候;

        PLL_USB:为USB HOST 控制器时钟

        FCLK: CPU 时钟(ARM926)

        HCLK: AHB总线上的硬件模块时钟

        PCLK: PHB总线上的硬件模块时钟

           RTC:实时时钟

           WDT:看门狗时钟

           TIMER:定时器时钟

因为TIMER的时钟源是可以选择的,1KHZ或者PCLK,如果选择PCLK,那就得从上面的层级结构中算出PCLK频率为定时器所用,时钟管理看似可有可无,不过为了扩展,有还是比没有好。

 

下面就是实现了,发现clk在arm linux下,主要有2类,一类如  mach-s3c24xx之类的,自己管理clock,一类如 mach-epxxx使用common/clock.c 的代码,通过内核来管理clock,这个common对代码 是 Russell 写的,也是新提倡的方式,那我当然得用,直接把mach-epxxx/clock.c 和头文件copy过来,根据需要加以修改,ops都不需要,提供3个API就是了: enable / disable / get_rate,因为我们这块板子时钟操作比较简单,这已经够用了,就这样实现啦!~呵呵,没啥东西,对了,还需要在mach-xxx/include/mach/下加个 clkdev.h,复制其他人的就好了,为什么需要,看代码就知道了。

 

也就是说,在arm linux 下实现 clock 管理很简单,3个文件:

mach-xxx/clock.c

mach-xxx/clock.h

mach-xxx/include/mach/clkdev.c

需要的其他文件就是,注册一些时钟,做做工作,配置配置,需要用的时候,clk_get()就能得到,然后操作,相当简单。我们现在就是这样做的。

       

### STM32L431 Bootloader Tutorial and Information #### Overview of the STM32L431 Microcontroller The STM32L431 is a low-power microcontroller based on the ARM Cortex-M4 core, designed for applications requiring high performance with minimal power consumption. The device features various peripherals including UARTs, SPIs, I2Cs, ADCs, DACs, timers, and more. #### Structure of the Boot Process In an embedded system like the STM32L431, the boot process involves loading and executing code from non-volatile memory (such as Flash). For this specific SoC, the program image structure includes several segments such as `.text`, which contains executable instructions; `.data` for initialized global variables; and `.bss` for uninitialized data[^1]. #### Entry Point and Initialization For devices similar to the STM32F103RBT6 mentioned earlier, the entry point typically starts at reset handler defined within the vector table located usually at address `0x0800_0000`. Before reaching main(), initialization routines set up hardware components ensuring proper operation before user-defined functions begin execution. #### Memory Map Considerations Understanding the memory layout helps when configuring linker scripts or startup files necessary during compilation stages using tools like arm-none-eabi-gcc instead of arm-linux-gcc due to differences between bare-metal programming versus operating systems environments. #### Pre-execution Preparation Steps Before running any application-level software: - Power-on Reset occurs. - Internal clocks are configured. - System configuration settings applied via option bytes stored in flash. - Vector Table setup completed by placing it into SRAM/Flash depending upon use case requirements. #### Writing a Simple Bootloader Example A basic bootloader can be implemented following these guidelines: ```c #include "stm32l4xx_hal.h" void JumpToApplication(uint32_t *applicationAddress); int main(void){ HAL_Init(); // Check condition indicating whether to start bootloader or app uint32_t AppAddr = 0x0800C000; JumpToApplication((uint32_t *)AppAddr); } // Function responsible for jumping to another part of flash where firmware resides void JumpToApplication(uint32_t *applicationAddress){ typedef void (*appFunction)(void); appFunction jump_to_app; /* Enable instruction cache */ SCB_EnableICache(); /* Disable write buffer */ SCB_DisableDCache(); /* Remap RAM to AHBS starting address */ HAL_DeInit(); __HAL_AFIO_REMAP_SWJ_DISABLE(); /* Set stack pointer */ __set_MSP(*(__IO uint32_t*)applicationAddress); jump_to_app = (appFunction)(*(__IO uint32_t*)(applicationAddress + 1)); jump_to_app(); } ``` --related questions-- 1. How does one configure the clock tree specifically for the STM32L4 series? 2. What steps should developers follow while creating custom linkerscript files tailored towards STM32 projects? 3. Can you explain how interrupt vectors work inside STM32 MCUs? 4. In what scenarios would someone choose to implement their own bootloader rather than relying on factory-provided ones?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值