diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ca2152d..02b0dd76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
 ## [Unreleased]
 
 - Fix `enumeratedValues` with `isDefault` only
+- Generate unique identifier instead of `DEVICE_PERIPHERALS` to solve
+  the link time issue when multiple devices used
 
 ## [v0.33.4] - 2024-06-16
 
diff --git a/src/generate/device.rs b/src/generate/device.rs
index dd601ada..8786d374 100644
--- a/src/generate/device.rs
+++ b/src/generate/device.rs
@@ -1,6 +1,8 @@
 use crate::svd::{array::names, Device, Peripheral};
 use proc_macro2::{Span, TokenStream};
 use quote::{quote, ToTokens};
+use regex::Regex;
+use syn::Ident;
 
 use log::debug;
 use std::fs::File;
@@ -270,12 +272,22 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
         }
     }
 
+    // Generate unique identifier to prevent linkage errors when using multiple devices.
+    let mut id = String::from("TAKEN_");
+    let re = Regex::new(r"[^A-Za-z0-9_]").unwrap();
+    let result = re.replace_all(&d.name, "_");
+    for ch in result.chars() {
+        id.extend(ch.to_uppercase());
+    }
+
+    let taken: Ident = syn::parse_str(&id)?;
+
     out.extend(quote! {
         // NOTE `no_mangle` is used here to prevent linking different minor versions of the device
         // crate as that would let you `take` the device peripherals more than once (one per minor
         // version)
         #[no_mangle]
-        static mut DEVICE_PERIPHERALS: bool = false;
+        static mut #taken: bool = false;
 
         /// All the peripherals.
         #[allow(non_snake_case)]
@@ -290,12 +302,12 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
             pub fn take() -> Option<Self> {
                 critical_section::with(|_| {
                     // SAFETY: We are in a critical section, so we have exclusive access
-                    // to `DEVICE_PERIPHERALS`.
-                    if unsafe { DEVICE_PERIPHERALS } {
+                    // to `#taken`.
+                    if unsafe { #taken } {
                         return None
                     }
 
-                    // SAFETY: `DEVICE_PERIPHERALS` is set to `true` by `Peripherals::steal`,
+                    // SAFETY: `#taken` is set to `true` by `Peripherals::steal`,
                     // ensuring the peripherals can only be returned once.
                     Some(unsafe { Peripherals::steal() })
                 })
@@ -308,7 +320,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
             /// Each of the returned peripherals must be used at most once.
             #[inline]
             pub unsafe fn steal() -> Self {
-                DEVICE_PERIPHERALS = true;
+                #taken = true;
 
                 Peripherals {
                     #exprs