Hầu hết tất cả các thiết bị IC số đều cần một cách để đồng bộ hoạt động của các mạch điện bên trong IC hoặc để đồng bộ IC với các mạch khác ở bên ngoài khi giao tiếp với nhau. Và tín hiệu clock đã được sử dụng cho mục đích này. Tín hiệu clock là một tín hiệu dao động định kỳ, với thông số quan trọng nhất mà chúng ta thường biết đến là tần số, được thể hiện bằng đơn vị Hertz. Người ta thường ví tín hiệu clock giống như nhịp tim của thiết bị điện tử.
Tần số clock bên trong vi điều khiển liên quan trực tiếp đến hiệu năng và mức độ tiêu thụ năng lượng bên trong vi điều khiển. Điều này đòi hỏi clock phải được thiết kế để có thể lựa chọn các nguồn cung cấp clock khác nhau. Và clock phải được tổ chức theo một cấu trúc phân cấp, và phải được thiết kế để có thể thực hiện được việc bật/tắt, cấu hình tốc độ riêng biệt cho các khối khác nhau bên trong vi điều khiển.
Hình 1. Clock tree của vi điều khiển STM32F303
Hãng ST đã thiết kế và cung cấp cho người dùng khả năng làm việc với toàn bộ clock tree của vi điều khiển STM32 một cách đơn giản nhất thông qua Giao diện STM32CubeMX và module RCC của thư viện HAL. Chi tiết về Clock tree và các kiến thức cần thiết để các bạn có thể thiết kế và quản lý clock cho các ứng dụng sử dụng dòng vi điều khiển STM32 đã được mình trình bày trong khóa học Lập trình Vi điều khiển STM32 – Vi xử lý ARM Cortex M3/4.
Trong bài viết này, chúng ta sẽ tìm hiểu về Clock Security System (CSS) của vi điều khiển STM32 và làm rõ chức năng này qua các ví dụ thực tế.
1. Nguồn clock cho System clock (SYSCLK) vi điều khiển
- Có 3 nguồn clock phổ biến khác nhau có thể được sử dụng làm System Clock gồm HSI, HSE, PLL.
- Khi vi điều khiển khởi động, nguồn dao động HSI được lựa chọn làm SYSCLK.
- Một sự chuyển đổi từ nguồn clock này sang nguồn clock khác có thể xảy ra nếu nguồn clock khác sẵn sàng (đã được cấu hình enable và ổn định sau thời gian khởi động). Nếu một nguồn clock chưa sẵn sàng được chọn làm System Clock thì sẽ xảy ra sự chuyển đổi để sử dụng nguồn clock đã sẵn sàng. Khi debug, chúng ta có thể thấy các bit status trong thanh ghi Clock Control Register (RCC_CR) thể hiện các nguồn clock sẵn sàng và nguồn clock nào được sử dụng để làm System Clock.
Hình 2. Thanh ghi điều khiển clock RCC_CR
Thử nghiệm thực tế:
Phần cứng: Các bạn cũng có thể thử nghiệm trên các board mạch STM32 có nguồn dao động ngoài từ thạch anh như STM32F103 Blue Pill hoặc các board mạch STM32 Discovery hoặc các board mạch có dao động ngoài từ phần mạch Debugger STLink đính kèm như board mạch Nucleo (xem sơ đồ nguyên lý và tài liệu User Manual Board để hiểu rõ hơn)
Hình 3. Board STM32 Nucleo chưa được hàn thạch anh nhưng được cấp dao động ngoài từ phần mạch Debugger STLink tích hợp
Phần mềm: Cấu hình cho vi điều khiển sử dụng bộ dao động ngoại (RCC > High Speed Clock (HSE) > Crystal/Ceramic Resonator).
Hình 4. Cấu hình nguồn Clock HSE cho vi điều khiển
Trong chương trình chính, build chương trình và vào debug. Đặt Breakpoint tại hàm SystemClock_Config, phân tích các bit trạng thái tại thanh ghi Clock Control Register (RCC_CR).
- Bấm Run, khi chương trình dừng lại tại Breakpoint thì hàm SystemClock_Config() chưa được thực thi. Có thể thấy được bit HSION trong thanh ghi CR đang có giá trị là 1, tức là khi khởi động hệ thống mặc định chọn HSI làm clock.
Hình 5. Giá trị thanh ghi RCC_CR khi vi điều khiển khởi động
- Bấm Step Over để SystemClock_Config() được thực thi. Lúc này, ta thấy bit HSEON đã được bật và HSE clock đã sẵn sàng. Bit SW ở thanh ghi Clock Configuration Register (RCC_CFGR) có giá trị là 1 chỉ ra HSE đã được sử dụng cho SYSCLK
2. Clock Security system (CSS) vi điều khiển STM32
- Clock Security System là một tính năng của hệ thống clock vi điều khiển STM32 và có thể được kích hoạt bằng phần mềm. Điều này sẽ dẫn đến kích hoạt Clock Detector sau khoảng thời gian khởi động nguồn clock HSE và CSS sẽ bị tắt đi khi nguồn clock HSE bị dừng.
- Nếu có lỗi được phát hiện với nguồn clock HSE, thì HSE sẽ được tắt đi tự động, một xung clock báo sự kiện lỗi HSE được gửi đi để “break input” các Advanced-Control Timers (hầu hết các tính năng của Timer phụ thuộc vào nguồn clock) và một tín hiệu yêu cầu ngắt CSSI được tạo ra cho phép vi điều khiển thực hiện các hoạt động cảnh báo và xử lý an toàn.
Hình 7. Thanh ghi cấu hình clock RCC_CFGR
Thử nghiệm thực tế:
Phần cứng: Các bạn cũng có thể thử nghiệm trên các board mạch STM32 không có nguồn dao động ngoài hoặc tháo thạch anh 8MHz ở board mạch STM32F103 BluePill hay board mạch STM32Discovery hoặc tháo cầu SB dẫn tín hiệu từ phần mạch Debuger STLink tích hợp của các board STM32Nucleo. Các bạn cũng có thể tác động vào các board mạch có sẵn nguồn dao động ngoại để làm lỗi tạm thời nguồn dao động ngoài (lưu ý: việc này không khuyến khích, thao tác không cẩn thận có thể làm hỏng vi điều khiển/ board mạch).
Phần mềm:
- Kích hoạt tính năng phát hiện mất clock HSE bằng cách enable CSS trong Clock Configuration tại gia diện cấu hình CubeMX hoặc các bạn tự gọi hàm HAL_RCC_EnableCSS() trong hàm main.
Hình 8. Cấu hình Enable CSS
- Cấu hình Enable RCC Interrupt tại khối NVIC để tín hiệu yêu cầu ngắt từ CSS gửi đến NVIC có thể kích hoạt vi xử lý thực thi trình phục vụ ngắt.
- Nếu các bạn nhấn chọn Enable CSS trong clock configuration như hình trên thì hàm HAL_RCC_EnableCSS() sẽ được sinh ra tự động bên trong hàm SystemClock_Config(void)
1 2 3 4 5 6 7 |
void SystemClock_Config(void) { … /** Enables the Clock Security System */ HAL_RCC_EnableCSS(); } |
- Nếu các bạn không cấu hình tại giao diện CubeMX thì có thể tự thêm bằng cách gọi HAL_RCC_EnableCSS() ngay sau sau hàm SystemClock_Config();
1 2 3 4 5 6 |
/* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ HAL_RCC_EnableCSS(); /* USER CODE END SysInit */ |
- Vì lý do ngắt CSS được liên kết với NMI của lõi ARM Cortex M nên hàm HAL_RCC_NMI_IRQHandler() sẽ được gọi trong hàm void NMI_Handler(void) (trong tập tin stm32…_it.c). Việc này được thực hiện tự động nếu các bạn tích chọn Enabel CSS tại giao diện CubeMX. Nếu không, các bạn cần tự thực hiện việc liên kết gọi hàm này.
- Thư viện HAL đã thiết kế hàm HAL_RCC_NMI_IRQHandler() gọi hàm HAL_RCC_CSSCallback() và hàm callback này được định nghĩa với từ khóa weak nên các bạn định nghĩa lại tại tập tin main.c và viết nội dung cần xử lý tại đây.
1 2 3 4 |
void HAL_RCC_CSSCallback(void) { __NOP(); //Chuyển qua sử dụng nguồn HSI khi có vấn đề với HSE } |
Ta thấy, khi chương trình đang chạy bằng HSE, bit SW = 1, cho thấy HSE đang được sử dụng làm clock cho hệ thống.
Hình 9. Giá trị bit SW tại thanh ghi CFGR khi HSE bình thường
Khi có vấn đề xảy ra với HSE (mình đã tác động để làm HSE lỗi), chương trình đã nhảy vào hàm HAL_RCC_CSSCallback() để thực thi chương trình bên trong hàm ngắt, Có thể thấy tại hình 10, chương trình đã dừng lại tại break point.
Hình 10. Giá trị bit SW tại thanh ghi CFGR khi HSE gặp sự cố
Bit SW trong thanh ghi CFGR đã bị reset về 0, lúc này HSI sẽ được chọn làm clock cho hệ thống thay thế cho HSE.
Lưu ý: Nếu HSE được sử dụng một cách trực tiếp hay gián tiếp thông qua PLL thì khi HSE bị vô hiệu hóa vì lỗi thì PLL cũng sẽ bị vô hiệu hóa và HSI được sử dụng trực tiếp làm nguồn vào cho SYSCLK. Các bạn cần lưu ý các giá trị tần số sẽ ảnh hưởng như thế nào trong ứng dụng của các bạn và có những giải pháp phù hợp.
Chúc các bạn thành công!
Cộng đồng Kỹ thuật TAPIT
Binh Hoang, Tai Pham, Thuong Nguyen