Multi Source Translation Content

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Multi Source Translation Content

Discussions

Sort by:
Seeking guidance: se05x_Minimal fails in OP-TEE environment Hello NXP Community, I am attempting to run se05x_Minimal on our target board running Linux with OP-TEE. Following the solution recommended in this community post (How to integrate Plug and Trust MW into OP-TEE), we built the environment accordingly. In particular, for Step 2, we configured the setup without enabling "keep CAAM enabled". As a result of this configuration, the I2C bus connected to SE05x is managed by OP-TEE (Secure World), and the standard Linux I2C device node /dev/i2c-1 is not visible/available in the Normal World (Linux). When executing `./se05x_Minimal` directly from the Linux user-space console, we encounter the following error: App :INFO :Running ./se05x_Minimal App :INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments. App :INFO :PlugAndTrust_v04.07.01_20250519 App :INFO :Using default PlatfSCP03 keys. You can use keys from file using ENV=EX_SSS_BOOT_SCP03_PATH smCom :ERROR:opening failed... Failed to open the i2c bus: No such file or directory smCom :INFO :Pass i2c device address in the format : . smCom :INFO :Example ./example /dev/i2c-1:0x48 OR ./example /dev/i2c-1 smCom :ERROR:phPalEse_i2c_open_and_configure Failed retry smCom :ERROR:I2C init Failed: retval d smCom :ERROR:phPalEse_Init Failed smCom :ERROR: Failed to create physical connection with ESE sss :ERROR:SM_I2CConnect Failed. Status 7012 App :ERROR:sss_session_open failed App :ERROR:ex_sss_session_open Failed App :ERROR:!ERROR! ret != 0. Environment & Hardware Setup: Evaluation Board: MCIMX8M-WEVK (i.MX 8M Dual/Quad) Secure Element Board: OM-SE051ARD Secure Element: SE05x (Plug & Trust MW v04.07.01) OS: Linux (Normal World) + OP-TEE (Secure World) Middleware Options (CMake): -DPTMW_Host=iMXLinux, -DPTMW_SMCOM=T1oI2C Note: se05x_Minimal works fine if Linux kernel-space direct I2C (/dev/i2c-1) is enabled. It appears smCom is still attempting to open the physical Linux I2C device (/dev/i2c-X), which no longer exists in our Normal World environment. Could you please provide instructions on what we need to do or modify so that se05x_Minimal can run successfully in this setup? SE050 Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li  Thank you very much for your detailed explanation and the C code samples. Following your guidance, we implemented a C application using the standard PKCS#11 API (libckteec.so.0) under Option 1 (OP-TEE exclusive I2C setup). All operations -- including key generation, AES encrypt/decrypt, RSA sign/verify, and RSA encrypt/decrypt -- are now working completely as expected. We appreciate your support in resolving this issue. Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment Hi @Uc_S , This is an excellent and important question. The short answer is: In Option 1 (OP-TEE exclusive I2C), the Plug & Trust MW SSS APIs cannot be used from Linux userspace directly. You must use the standard PKCS#11 C API via libckteec.so . Below is a detailed explanation and complete C code samples for all the operations you need. Why SSS APIs Cannot Be Used in This Setup The Plug & Trust MW SSS APIs ( sss_session_open , sss_key_store_set_key , sss_asymmetric_sign_digest , etc.) rely on a transport layer to communicate with the SE051. All supported transports ( T1oI2C , JRCP_V1_AM , etc.) ultimately require either Linux I2C access or a proxy server — neither of which is available when OP-TEE exclusively owns the I2C bus. The correct path in the OP-TEE exclusive setup is: Your C App → PKCS#11 C API (cryptoki.h) → libckteec.so → OP-TEE PKCS#11 TA → SE051 libckteec is provided by optee-client and implements the Cryptoki interface with the OP-TEE PKCS#11 TA as its backend. The TA in turn routes crypto operations to SE051 via OP-TEE's native I2C driver. Required Headers and Linking #include /* Standard Cryptoki header — from optee-client or OpenSC */ Compile and link: gcc -o my_app my_app.c -ldl # Or link directly: gcc -o my_app my_app.c /usr/lib/libckteec.so.0 At runtime, set the module path if using dynamic loading: #define PKCS11_MODULE "/usr/lib/libckteec.so.0" Initialization and Token Setup (call once at startup) #include #include #include #define CHECK_RV(rv, msg) \ if ((rv) != CKR_OK) { fprintf(stderr, "%s failed: 0x%lX\n", (msg), (rv)); goto cleanup; } /* User PIN — must match what was set with pkcs11-tool --init-pin */ static CK_UTF8CHAR user_pin[] = "1234"; static CK_ULONG user_pin_len = 4; CK_FUNCTION_LIST *p11 = NULL; /* Global function list pointer */ CK_SESSION_HANDLE session = CK_INVALID_HANDLE; int pkcs11_init(void) { CK_RV rv; CK_ULONG slot_count = 0; CK_SLOT_ID slot_id; CK_SLOT_ID slot_list[8]; /* Load function list — if using dynamic linking, use C_GetFunctionList() */ rv = C_Initialize(NULL_PTR); CHECK_RV(rv, "C_Initialize"); /* Get available slots */ rv = C_GetSlotList(CK_TRUE, NULL_PTR, &slot_count); CHECK_RV(rv, "C_GetSlotList (count)"); rv = C_GetSlotList(CK_TRUE, slot_list, &slot_count); CHECK_RV(rv, "C_GetSlotList"); slot_id = slot_list[0]; /* Use first slot — OP-TEE PKCS#11 TA */ /* Open a read-write session */ rv = C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session); CHECK_RV(rv, "C_OpenSession"); /* Login as normal user */ rv = C_Login(session, CKU_USER, user_pin, user_pin_len); CHECK_RV(rv, "C_Login"); return 0; cleanup: return -1; } void pkcs11_cleanup(void) { C_Logout(session); C_CloseSession(session); C_Finalize(NULL_PTR); } Operation 1: Generate an RSA Key Pair and Store in SE051 int generate_rsa_keypair(CK_OBJECT_HANDLE *pub_key, CK_OBJECT_HANDLE *priv_key) { CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_ULONG key_bits = 2048; CK_BYTE pub_exponent[] = { 0x01, 0x00, 0x01 }; /* 65537 */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; /* Key ID stored in SE051 NVM — choose a unique 4-byte ID */ CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_ATTRIBUTE pub_tmpl[] = { { CKA_MODULUS_BITS, &key_bits, sizeof(key_bits) }, { CKA_PUBLIC_EXPONENT, pub_exponent, sizeof(pub_exponent) }, { CKA_VERIFY, &ck_true, sizeof(ck_true) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_ID, key_id, sizeof(key_id) }, }; CK_ATTRIBUTE priv_tmpl[] = { { CKA_SIGN, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID, key_id, sizeof(key_id) }, }; rv = C_GenerateKeyPair(session, &mech, pub_tmpl, sizeof(pub_tmpl) / sizeof(pub_tmpl[0]), priv_tmpl, sizeof(priv_tmpl) / sizeof(priv_tmpl[0]), pub_key, priv_key); CHECK_RV(rv, "C_GenerateKeyPair"); printf("RSA-2048 key pair generated. Private key stays in SE051 NVM.\n"); return 0; cleanup: return -1; } Operation 2: Generate an AES Key and Store in SE051 int generate_aes_key(CK_OBJECT_HANDLE *aes_key) { CK_RV rv; CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; CK_ULONG key_len = 32; /* 256-bit AES */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; CK_BYTE key_id[] = { 0x20, 0x00, 0x00, 0x01 }; CK_ATTRIBUTE aes_tmpl[] = { { CKA_VALUE_LEN, &key_len, sizeof(key_len) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID, key_id, sizeof(key_id) }, }; rv = C_GenerateKey(session, &mech, aes_tmpl, sizeof(aes_tmpl) / sizeof(aes_tmpl[0]), aes_key); CHECK_RV(rv, "C_GenerateKey (AES)"); printf("AES-256 key generated and stored in SE051.\n"); return 0; cleanup: return -1; } Operations 3 & 4: AES-CBC Encrypt / Decrypt int aes_encrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *plaintext, CK_ULONG plaintext_len, CK_BYTE *ciphertext, CK_ULONG *ciphertext_len) { CK_RV rv; CK_BYTE iv[16] = { 0 }; /* All-zero IV for example; use a random IV in production */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_EncryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_EncryptInit"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, ciphertext, ciphertext_len); CHECK_RV(rv, "C_Encrypt"); return 0; cleanup: return -1; } int aes_decrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *ciphertext, CK_ULONG ciphertext_len, CK_BYTE *plaintext, CK_ULONG *plaintext_len) { CK_RV rv; CK_BYTE iv[16] = { 0 }; /* Must match the IV used for encryption */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_DecryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_DecryptInit"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, plaintext, plaintext_len); CHECK_RV(rv, "C_Decrypt"); return 0; cleanup: return -1; } Operations 5 & 6: RSA Sign (private key stays in SE051) and Verify int rsa_sign(CK_OBJECT_HANDLE priv_key, const CK_BYTE *data, CK_ULONG data_len, CK_BYTE *signature, CK_ULONG *sig_len) { CK_RV rv; /* SHA256-PKCS1v1.5 — SE051 computes SHA-256 digest internally then signs */ CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_SignInit(session, &mech, priv_key); CHECK_RV(rv, "C_SignInit"); rv = C_Sign(session, (CK_BYTE *)data, data_len, signature, sig_len); CHECK_RV(rv, "C_Sign"); printf("RSA signature generated (%lu bytes). Private key never left SE051.\n", *sig_len); return 0; cleanup: return -1; } int rsa_verify(CK_OBJECT_HANDLE pub_key, const CK_BYTE *data, CK_ULONG data_len, const CK_BYTE *signature, CK_ULONG sig_len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_VerifyInit(session, &mech, pub_key); CHECK_RV(rv, "C_VerifyInit"); rv = C_Verify(session, (CK_BYTE *)data, data_len, (CK_BYTE *)signature, sig_len); if (rv == CKR_OK) { printf("Signature verification: SUCCESS\n"); return 0; } else if (rv == CKR_SIGNATURE_INVALID) { printf("Signature verification: INVALID\n"); return 1; } CHECK_RV(rv, "C_Verify"); cleanup: return -1; } Operations 7 & 8: RSA Encrypt / Decrypt int rsa_encrypt(CK_OBJECT_HANDLE pub_key, const CK_BYTE *plaintext, CK_ULONG plaintext_len, CK_BYTE *ciphertext, CK_ULONG *ciphertext_len) { CK_RV rv; /* RSA-OAEP with SHA-256 — recommended over PKCS1 v1.5 for new designs */ CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg = CKM_SHA256, .mgf = CKG_MGF1_SHA256, .source = CKZ_DATA_SPECIFIED, .pSourceData = NULL, .ulSourceDataLen = 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_EncryptInit(session, &mech, pub_key); CHECK_RV(rv, "C_EncryptInit (RSA-OAEP)"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, ciphertext, ciphertext_len); CHECK_RV(rv, "C_Encrypt (RSA-OAEP)"); return 0; cleanup: return -1; } int rsa_decrypt(CK_OBJECT_HANDLE priv_key, const CK_BYTE *ciphertext, CK_ULONG ciphertext_len, CK_BYTE *plaintext, CK_ULONG *plaintext_len) { CK_RV rv; CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg = CKM_SHA256, .mgf = CKG_MGF1_SHA256, .source = CKZ_DATA_SPECIFIED, .pSourceData = NULL, .ulSourceDataLen = 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_DecryptInit(session, &mech, priv_key); CHECK_RV(rv, "C_DecryptInit (RSA-OAEP)"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, plaintext, plaintext_len); CHECK_RV(rv, "C_Decrypt (RSA-OAEP)"); printf("RSA decryption completed. Private key never left SE051.\n"); return 0; cleanup: return -1; } Accessing Existing Keys (without regenerating) If a key was previously generated and stored in SE051, retrieve it by CKA_ID without calling C_GenerateKey again: int find_key_by_id(CK_BYTE *key_id, CK_ULONG key_id_len, CK_OBJECT_CLASS obj_class, CK_OBJECT_HANDLE *handle) { CK_RV rv; CK_ULONG obj_count = 0; CK_ATTRIBUTE search_tmpl[] = { { CKA_CLASS, &obj_class, sizeof(obj_class) }, { CKA_ID, key_id, key_id_len }, }; rv = C_FindObjectsInit(session, search_tmpl, sizeof(search_tmpl) / sizeof(search_tmpl[0])); CHECK_RV(rv, "C_FindObjectsInit"); rv = C_FindObjects(session, handle, 1, &obj_count); CHECK_RV(rv, "C_FindObjects"); C_FindObjectsFinal(session); if (obj_count == 0) { fprintf(stderr, "Key not found in SE051\n"); return -1; } return 0; cleanup: C_FindObjectsFinal(session); return -1; } Usage example: CK_OBJECT_HANDLE priv_key; CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_OBJECT_CLASS priv_class = CKO_PRIVATE_KEY; find_key_by_id(key_id, sizeof(key_id), priv_class, &priv_key); Supported Mechanisms (verified on OP-TEE PKCS#11 TA + SE051) Operation Mechanism Constant Notes RSA key generation CKM_RSA_PKCS_KEY_PAIR_GEN 256–4096 bits AES key generation CKM_AES_KEY_GEN 16 or 32 bytes RSA sign/verify CKM_SHA256_RSA_PKCS PKCS#1 v1.5 RSA sign/verify (PSS) CKM_SHA256_RSA_PKCS_PSS PSS padding RSA encrypt/decrypt CKM_RSA_PKCS_OAEP OAEP recommended RSA encrypt/decrypt CKM_RSA_PKCS PKCS#1 v1.5 AES encrypt/decrypt CKM_AES_CBC_PAD CBC with PKCS#7 AES encrypt/decrypt CKM_AES_CBC CBC without padding AES encrypt/decrypt CKM_AES_CTR CTR mode ECC sign/verify CKM_ECDSA_SHA256 160–521 bits ECDH key agreement CKM_ECDH1_DERIVE   Can the SSS APIs Still Be Used at All? Yes — but only in the co-existence setup (Option 2) where Linux still has access to the I2C bus (i.e., the lf-6.12.y-i2c-disabled-se050 DTS patch has NOT been applied). In that case, you can use the SSS APIs as described in AN13030 Section 3.3 directly from Linux. If you choose Option 1 (OP-TEE exclusive), the Cryptoki/PKCS#11 C API shown above is the correct and only supported path from Linux userspace. Reference AN13030 Rev. 2.4, Section 3.3 — Full SSS API reference (for co-existence / non-OP-TEE builds) OP-TEE PKCS#11 TA test suite (pkcs11_1000.c): optee-test/host/xtest/pkcs11_1000.c — comprehensive C examples for all Cryptoki operations NXP GitHub: se05x-pkcs11 — NXP's PKCS#11 standalone library (alternative to libckteec.so for non-OP-TEE builds)   Hope that helps,   Have a great day, Kan ------------------------------------------------------------------------------- Note: - If this post answers your question, please click the "Mark Correct" button. Thank you! - We are following threads for 7 weeks after the last post, later replies are ignored Please open a new thread and refer to the closed one, if you have a related question at a later point in time. ------------------------------------------------------------------------------- Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li  Thank you very much for the clear and detailed explanation. We are currently considering using Option 1 or Option 2 depending on the stage of our future development (e.g., using Option 2 for initial testing/evaluation and Option 1 for production). Regarding Option 1 (OP-TEE PKCS#11 TA), we have a question about application development in C. If we would like to implement cryptographic operations such as key storage, signing / signature generation, signature verification, and encryption/decryption in a C program under Option 1, which approach should we take? Should we write a C program that directly calls standard PKCS#11 APIs (e.g., C_Initialize, C_CreateObject, C_SignInit, C_Sign, C_VerifyInit, C_Verify, etc.) via the OP-TEE PKCS#11 library (libckteec.so)? Or is it still possible/recommended to use the Plug & Trust MW SSS APIs (such as sss_key_store_set_key, sss_asymmetric_sign_digest, sss_asymmetric_verify_digest, sss_cipher_update, etc.) in this setup? If PKCS#11 APIs are required, could you please provide a simple sample code or reference guide for calling libckteec.so in C? Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment Hi @Uc_S , Thank you for the detailed report. The root cause is clear, and I can explain exactly why this happens and what your options are. Root Cause se05x_Minimal was built with -DPTMW_SMCOM=T1oI2C . This tells the smCom layer to open a physical Linux I2C device node ( /dev/i2c-X ) at session open time. Since you applied the lf-6.12.y-i2c-disabled-se050 DTS patch (Step 1 of the integration guide), that I2C controller is disabled in Linux Normal World — the device node simply does not exist. OP-TEE exclusively owns the I2C bus via CFG_IMX_I2C=y , and Linux cannot see or open it. This is by design — the DTS patch is what gives OP-TEE exclusive, uncontended access to SE051. The se05x_Minimal binary built with T1oI2C is fundamentally incompatible with this configuration. Your Two Options ✅ Option 1 — Use OP-TEE PKCS#11 TA (Recommended for Production) This is the intended Linux userspace path in the OP-TEE exclusive setup. Instead of running se05x_Minimal , use pkcs11-tool or OpenSSL with libckteec.so (the OP-TEE PKCS#11 TA library). The TA internally uses SE051 as its crypto backend via OP-TEE's native I2C driver. Quick verification that SE051 is reachable via PKCS#11: # List available PKCS#11 slots — SE051 should appear pkcs11-tool --module /usr/lib/libckteec.so.0 --list-slots # Get a random number from SE051 via OP-TEE pkcs11-tool --module /usr/lib/libckteec.so.0 --generate-random 16 | xxd If you see a slot and random bytes, SE051 is fully accessible through OP-TEE. There is no need to run se05x_Minimal — it duplicates what the PKCS#11 TA already provides. ✅ Option 2 — Co-existence Setup (Recommended for Development/Testing) If you specifically need to run se05x_Minimal and other Plug & Trust MW demos from Linux userspace, use the co-existence setup where Linux DTS still has I2C enabled (i.e., do not apply the I2C-disabled DTS patch). Steps: Step 1 — Revert the Linux DTS to keep I2C enabled in Normal World Build your imx8mq-evk.dtb (or equivalent) from the unmodified Linux DTS (without the lf-6.12.y-i2c-disabled-se050 patch). The I2C controller node for SE051 must remain enabled in Linux. Step 2 — Keep your existing cmake flags unchanged Your current cmake configuration is correct for co-existence: cmake -S . -B ./build/ -DPTMW_Applet=SE05X_C -DPTMW_SE05X_Ver=07_02 -DPTMW_Host=iMXLinux -DPTMW_SMCOM=T1oI2C -DPTMW_HostCrypto=OPENSSL -DPTMW_RTOS=Default -DPTMW_mbedTLS_ALT=None -DPTMW_SCP=SCP03_SSS -DPTMW_SE05X_Auth=PlatfSCP03 -DPTMW_Log=Silent -DCMAKE_BUILD_TYPE=Release -DPTMW_OpenSSL=3_0 -DPTMW_SE_RESET_LOGIC=1 Step 3 — Set the I2C port before running export EX_SSS_BOOT_SSS_PORT=/dev/i2c-1 ./se05x_Minimal Trade-off: In this mode, both OP-TEE and Linux share the I2C bus to SE051. OP-TEE uses it for RSA/ECC offload; Linux uses it for MW demos. Concurrent access is not arbitrated, which can cause APDU collisions under load. Acceptable for development, but not recommended for production. Summary Option I2C DTS se05x_Minimal OP-TEE exclusive Recommended For PKCS#11 TA ( libckteec.so ) Disabled ❌ Not needed ✅ Yes Production Co-existence (T1oI2C) Enabled ✅ Works ⚠️ Shared I2C Development/Testing Clarification on the Integration Guide The community post you referenced (Step 2 — without CAAM) configures OP-TEE to exclusively own I2C. The Linux-side MW compilation shown in that guide (with T1oI2C ) was intended for the initial verification step before switching to OP-TEE mode — not for use alongside the OP-TEE exclusive I2C setup. Once OP-TEE owns I2C exclusively, the correct Linux userspace interface is the OP-TEE PKCS#11 TA, not the Plug & Trust MW SSS API demos directly. Please let us know which option fits your use case and we can provide further guidance. Have a great day, Kan ------------------------------------------------------------------------------- Note: - If this post answers your question, please click the "Mark Correct" button. Thank you! - We are following threads for 7 weeks after the last post, later replies are ignored Please open a new thread and refer to the closed one, if you have a related question at a later point in time. -------------------------------------------------------------------------------
View full article
I2C read and write using s32k144 MBD toolbox Hello, I am using s32k144 to read and write data from an external EEPROM. I will attach the model below. I am able to write the data but the read returns 255+NACK as output. Am i missing something here Sriram_0-1737789999186.pngSriram_0-1737789999186.png Sriram_1-1737790013461.pngSriram_1-1737790013461.png Is there a way to specify the register address of the EEPROM in the I2Cmaster block Sriram_2-1737790096449.pngSriram_2-1737790096449.png Can you guys help me out with this issue. Thanks Re: I2C read and write using s32k144 MBD toolbox Hi, I am also facing the same issue with I2C communication using the S32K144 as the master and the ST M24C04 EEPROM as the slave. Since you are using the same microcontroller and EEPROM, I wanted to check whether you were able to find a solution. If you have resolved this issue, could you please share the solution or let me know what fixed it? Thank you in advance for your help. Re: I2C read and write using s32k144 MBD toolbox I m using M24C02-DRE EEPROM
View full article
i.MX93 M33 Can't Use System TCM RAM for Allocation We're evaluating the i.MX9352 for an IoT device. I've created an application for the M33 core for time-critical IO operations which include collecting a large number of samples from peripherals. For development purposes, I am loading and starting the M33 code from Linux with remoteproc. Code is written in C and using MPUXpresso 26.06.00 SDK. I got the code working well, but now I need a large buffer for samples (~24 kB). I have tried adding this as either a static array or heap allocated with `malloc`. In either case, I seem to tun out of RAM even though the compile output indicates there is plenty. Working Version: Here's the memory information for a build with a small buffer, which **works OK** (but the buffer is too small for our requirements). Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78300 B 129928 B 60.26% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 48016 B 108 KB 43.42% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. Here is some info from the ELF file: readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131dc 0x131dc RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3654 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37e0 0x00000 0x0ba10 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack Large Static Allocation: Here's the memory and ELF file info for a build with a **24 kB static allocated buffer**. I.e.: static uint32_t m_sample_queue[SAMPLE_QUEUE_LENGTH]; // SAMPLE_QUEUE_LENGTH = 6000 Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 72016 B 108 KB 65.12% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. ### (As expected, the `m_data` section has increased in size.) ### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x117d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack When I try to start this version in Linux with remoteproc, it fails to start and dmesg shows the following errors: [ +0.001258] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x117d0 [ +0.000021] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x117d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.008868] remoteproc remoteproc0: Boot failed: -22 Claude tells me this is a problem with the .bss .heap .stack section, because the PhysAddr is `0x0fff37a0` and the size is now `0x117d0`. `0x0fff37a0 + 0x117d0 = 0x10004f70` which exceeds the M33 Code TCM address range 0x0ffe0000 .. 0x10000000. The explaination was confusing but my interpretation is that the static initialisation has to go into the "code" section, causing it to overflow even though there is plenty of space in the "system" TCM range (the other 128 kB). So maybe this makes sense. Dynamic (Heap) Allocation: E.g.: uint32_t *p_sample_queue = malloc(SAMPLE_QUEUE_LENGTH, sizeof(uint32_t)); The default heap size available to C is only 1 kB, so malloc fails with our large buffer. I modified the CMake for the project to allocate a larger heap (32 kB) via __heap_size__ which feeds into the linker script: mcux_add_linker_symbol( SYMBOLS "__stack_size__=0x400 \ __heap_size__=0x8000 \ <---- Added __use_shmem__=1 \ __multicore__=1 \ " ) Build output and ELF file info: Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 103760 B 108 KB 93.82% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. #### ELF file info: #### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x193d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack This seems to make the problem WORSE, not better (.bss/.heap/.stack at PhysAddr 0x0fff37a0, size 0x193d0). [ +0.001320] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x193d0 [ +0.000019] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x193d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.002908] remoteproc remoteproc0: Boot failed: -22 I thought using heap allocation should allow the code section to be smaller and allocate the memory from the data section. The "m_data" section shown in the build output above is indeed bigger. I don't really understand the "PhysAddr", which matches the "Code TCM" range from the ref manual, even for things which should be in the "System TCM" region (I think?). The addresses under "VirtAddr" seem correct. Why does the ELF file still try to place this .bss/.heap/.stack data at PhysAddr 0x0fff37a0, why is it so big when using runtime heap allocation, and is there a way to allocate my large buffer in the "System TCM" region? Re: i.MX93 M33 Can't Use System TCM RAM for Allocation Hi @jcolebaker  You can choose to change the LMA for data/bss/heap/stack to System TCM. In the MCUX linker script, change the load address (AT) for the data segment from code TCM to System TCM, so that PhysAddr also falls at 0x2000_0000: .data : { ... } > m_data AT> m_data /* Do not use AT> m_text */ .bss : { ... } > m_data When LMA == VMA and both are in System TCM, PhysAddr becomes 0x2000_xxxx, which matches an entry in the {0x20000000, …, 0x00040000} (256 KB) range in remoteproc driver, allowing remoteproc to translate correctly. Best Regards, Zhiming
View full article
S32DS for ARM 2018.R1 デバッグ問題 ARM 2018.R1用のS32DSでチップのデバッグ時に問題が発生しS32K146、以下の通りです: 送信後にGDBバージョンを特定できませんでした:D:\S32DS\eclipse\./Cross_Tools/gcc-arm-none-eabi-4_9/bin/arm-none-eabi-gdb --version、応答: しかし、Jlinkはチップの編集や消去、プログラムが可能です。私はARM 2018.R1のS32DSでデバッグしていません。助けてください。ありがとうございます! Re: S32DS for ARM 2018.R1 debug Problem Hi@lyz あなたの質問の意味がよく分かりませんでした。エラーのスクリーンショットを投稿してもらえますか?
View full article
S32DS for ARM 2018.R1 调试问题 使用 S32DS for ARM 2018.R1 调试 S32K146 芯片时出现问题,具体如下: 发送以下命令后无法确定 GDB 版本:D:\S32DS\eclipse\../Cross_Tools/gcc-arm-none-eabi-4_9/bin/arm-none-eabi-gdb --version,响应如下: 但是,Jlink 可以连接、擦除和编程芯片。我现在无法使用 S32DS for ARM 2018.R1 进行调试,请帮帮我,谢谢! Re: S32DS for ARM 2018.R1 debug Problem 嗨@lyz 我不太明白你的问题。能否提供一下错误截图?
View full article
T1042NXE BSDLファイル こんにちは、このコンポーネントのBSDLファイルを探しています。 T1042NXE7PQB BGA780 ファイルを送ってもらえますか? よろしくお願いします。 Re: T1042NXE BSDL file こんにちは、 コンポーネントT1042NXE7PQBの BSDL ファイルは、 T1040/T1042 結合 BSDL ファイル(ファイル名: T1040_and_T1042_1.1.bsdl ) に含まれています。この単一のファイルはT1040とT1042の両方のプロセッサに適しています。 ダウンロード方法 このファイルはNXPの製品ページの「 Design Resources → Design Files → モデル」で直接入手可能です: T1040/42用BSDLファイル — ダウンロード(アカウント登録が必要です) ファイルコード: T1040-T1042-BSDL 改訂版:R1A(2019年2月20日) サイズ:110.13 KB よろしくお願いします。
View full article
HSE FWの真正性を確認する方法 今、NXPエンジニアが提供した「HseLib_HseFwInstall」ソフトウェアを使ってHSE FWをインストールしました。 お客様から質問があります:HSE FW自体に署名がないと考えているため、HSE FWの真正性をどのように確認すればよいか。 屏幕截图 2026-09-17 182416.png 画面截图 2026-09-17 182416.png 改ざんされやすいと。 HSEのFWの真正性を証明するためのセキュリティ制度があると教えてくれる人はいますか? Re: How to confirm HSE FW authenticity おそらく新しいチケットを作成することも可能です: https://www.nxp.com/support/support:SUPPORTHOME HSE文書は安全なファイルなので、すでに手続きを済ませている場合は以下の手順に従う必要があります。 https://www.nxp.com/docs/en/user-guide/nxp-secure-access-rights-registration.pdf プレゼンテーションを共有できるかもしれません。 Re: How to confirm HSE FW authenticity この質問に答えてくださりありがとうございます。これらの内容に関する参考文献をどうやって見つければよいか教えていただけますか?In まだこれらの内容には気づいていません。 Re: How to confirm HSE FW authenticity こんにちは、 HSE FWは確かに保護されており、単なる署名なしバイナリではありません。 ファームウェアイメージは、配布前にNXPによって暗号化および署名されます。 NXPは製造時にHSEサブシステムに ROM鍵 を事前プログラムします(ハードウェアの信頼の基点)。これらの鍵は外部からは決してアクセスできません。 インストール中、オンチップのセキュアBAFは、イメージをフラッシュメモリに書き込む前に、これらのROMキーを使用してイメージを認証します。改ざんされた画像は拒否されます。 結論として、NXPの秘密署名鍵がなければ、改変されたHSEファームウェアをインストールすることは不可能です。その信頼はシリコンに根ざしている。
View full article
T1042NXE BSDL 文件 您好,我正在寻找该组件的BSDL文件: T1042NXE7PQB BGA780 你能把文件发给我吗? 谢谢! Re: T1042NXE BSDL file 你好, 您的元器件T1042NXE7PQB的 BSDL 文件包含在T1040/T1042 组合 BSDL 文件(文件名: T1040_and_T1042_1.1.bsdl )中。这个文件同时适用于 T1040 和 T1042 处理器。 如何下载 该文件可直接在 NXP 产品页面的“设计资源”→“设计文件”→“模型”下找到: T1040/42 的 BSDL 文件 — 下载(需要账号) 文件代码: T1040-T1042-BSDL 修订版:R1A(2019年2月20日) 大小:110.13 KB 此致
View full article
如何确认 HSE FW 的真伪 现在,我使用了NXP工程师提供的“HseLib_HseFwInstall”软件来安装HSE固件。 我们的客户提出了一个问题:如何确认 HSE 固件的真伪,因为他认为 HSE 固件本身没有任何签名。这很容易。 屏幕截图 2026-09-17 182416.png屏幕截图2026-09-17 182416.png被篡改。 谁能告诉我 HSE FW 是否有网络安全措施来确认 HSE FW 的真实性? Re: How to confirm HSE FW authenticity 或许您可以创建一个新的工单: https://www.nxp.com/support/support:SUPPORTHOME HSE 文件属于安全文件,因此除非您之前已经操作过,否则需要遵循以下步骤: https://www.nxp.com/docs/en/user-guide/nxp-secure-access-rights-registration.pdf 我们可以一起做一些演示。 Re: How to confirm HSE FW authenticity 感谢您回答这个问题。请问我该如何找到关于这些内容的参考资料?我在《RM758222-HSE-B 固件参考手册 - V2.2》中还没有注意到这些内容。 Re: How to confirm HSE FW authenticity 您好, HSE固件确实受到保护——它不是普通的未签名二进制文件。 固件镜像在分发前由 NXP 进行加密和签名。 NXP 在制造过程中将ROM 密钥预先编程到 HSE 子系统中(硬件信任根)。这些密钥永远无法从外部获取。 安装过程中,片上安全 BAF会使用这些 ROM 密钥来验证映像,然后再将其写入闪存。篡改过的图片会被拒绝。 结论是:如果没有 NXP 的私钥,就不可能安装修改过的 HSE 固件。信任源于硅谷。
View full article
How to confirm HSE FW authenticity Now,I Used  “HseLib_HseFwInstall”software witch is supply by NXP engineer to install HSE FW。 Our customer raise a question: how to confirm HSE FW authenticity, because he think HSE FW itself don't have any signature,.it is easy 屏幕截图 2026-09-17 182416.png屏幕截图 2026-09-17 182416.pngto be tampered. Who can tell me HSE FW weather have some security scheme to comfirm HSE FW authenticity? Re: How to confirm HSE FW authenticity Possibly you could create new ticket: https://www.nxp.com/support/support:SUPPORTHOME HSE documents are secure files, so following procedure is needed to follow unless you have already done it before: https://www.nxp.com/docs/en/user-guide/nxp-secure-access-rights-registration.pdf We could possibly share some presentation. Re: How to confirm HSE FW authenticity Thank you for answer this question.Could you tell me how can I find these reference about these contents.In I haven't noticed these contents yet. Re: How to confirm HSE FW authenticity Hi, HSE FW is indeed protected — it is not plain unsigned binary. The FW image is encrypted and signed by NXP before distribution. NXP pre-programs ROM keys into the HSE subsystem during manufacturing (hardware Root of Trust). These keys are never accessible externally. During installation, the on-chip Secure BAF uses those ROM keys to authenticate the image before writing it to flash. A tampered image is rejected. Bottom line: without NXP's private signing key, it is impossible to install a modified HSE FW. The trust is rooted in silicon.
View full article
T1042NXE BSDL file Hello, i'm looking for the BSDL file for this component : T1042NXE7PQB BGA780 Can you send me the file ? Thanks Re: T1042NXE BSDL file Hello, The BSDL file for your component T1042NXE7PQB is covered by the T1040/T1042 combined BSDL file (filename: T1040_and_T1042_1.1.bsdl ). This single file is suitable for both the T1040 and T1042 processors. How to Download The file is available directly on the NXP product page under Design Resources → Design Files → Models: BSDL file for T1040/42 — Download (Account Required) File code: T1040-T1042-BSDL Revision: R1A (Feb 20, 2019) Size: 110.13 KB Regards
View full article
ガイダンスを求めています: OP-TEE 環境で se05x_Minimal が失敗します こんにちは、NXPコミュニティの皆さん、 ターゲットボード上でLinuxをOP-TEEで動se05x_Minimalかそうとしています。 このコミュニティ投稿( Plug and Trust MWをOP-TEEに統合する方法)で推奨されている解決策に従って、それに応じた環境を構築しました。 特に、ステップ2では、「CAAMを有効にする」を有効にせずに設定を構成しました。 この構成の結果、SE05xに接続されたI2CバスはOP-TEE(Secure World)によって管理され、標準的なLinuxのI2Cデバイスノード/dev/i2c-1はNormal World(Linux)では表示・利用できません。 Linuxユーザー空間コンソールから直接「./se05x_Minimal」を実行すると、以下のエラーが発生します: App :INFO :Running ./se05x_Minimal App :INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments. App :INFO :PlugAndTrust_v04.07.01_20250519 App :INFO :Using default PlatfSCP03 keys. You can use keys from file using ENV=EX_SSS_BOOT_SCP03_PATH smCom :ERROR:opening failed... Failed to open the i2c bus: No such file or directory smCom :INFO :Pass i2c device address in the format : . smCom :INFO :Example ./example /dev/i2c-1:0x48 OR ./example /dev/i2c-1 smCom :ERROR:phPalEse_i2c_open_and_configure Failed retry smCom :ERROR:I2C init Failed: retval d smCom :ERROR:phPalEse_Init Failed smCom :ERROR: Failed to create physical connection with ESE sss :ERROR:SM_I2CConnect Failed. Status 7012 App :ERROR:sss_session_open failed App :ERROR:ex_sss_session_open Failed App :ERROR:!ERROR! ret != 0. 環境およびハードウェアセットアップ:評価ボード:MCIMX8M-WEVK(i.MX 8M デュアル/クアッド) セキュアエレメントボード:OM-SE051ARD セキュアエレメント:SE05x(Plug & Trust MW v04.07.01) OS:Linux(ノーマルワールド)+ OP-TEE(セキュアワールド) ミドルウェアオプション(CMake):-DPTMW_Host=iMXLinux、-DPTMW_SMCOM=T1oI2C 注:Linuxカーネル空間のダイレクトI2C(/dev/i2c-1)が有効se05x_Minimalなら問題なく動作します。 smComは、もはやノーマルワールド環境には存在しない物理的なLinux I2Cデバイス(/dev/i2c-X)をまだ開こうとしているようです。 この環境で正常に動作させるために、何をすべきか、何を修正すべきか指示se05x_Minimal教えていただけますか? SE050 Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li 詳細な説明とC言語のサンプルコードをありがとうございました。 ご指導に従い、標準のPKCS#11 API(libckteec.so.0)を用いて、オプション1(OP-TEE独占I2Cセットアップ)でCアプリケーションを実装しました。 鍵生成、AESの暗号化/復号、RSA署名/検証、RSA暗号化/復号を含むすべての操作が、期待通りに完全に動作しています。 この問題解決へのサポートに感謝いたします。 Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment こんにちは、 @Uc_S さん。 これは非常に優れた、そして重要な質問です。簡潔に答えると次のようになります。 オプション1(OP-TEE専用I2C)では、Plug & Trust MW SSS APIはLinuxユーザースペースから直接使用できません。 libckteec.so を介して標準の PKCS#11 C API を使用する必要があります。 以下に、必要なすべての操作に関する詳細な説明と完全なC言語のコードサンプルを示します。 なぜこの構成ではSSS APIを使えないのか Plug & Trust MW SSS API ( sss_session_open 、 sss_key_store_set_key 、 sss_asymmetric_sign_digest など) は、SE051 と通信するためにトランスポート層に依存しています。サポートされているすべてのトランスポート( T1oI2C 、 JRCP_V1_AM など)は最終的にLinux I2Cアクセスかプロキシサーバーを必要としますが、OP-TEEがI2Cバスを独占的に所有している場合、どちらも利用できません。 OP-TEE排他設定における正しいパスは次のとおりです。 Your C App → PKCS#11 C API (cryptoki.h) → libckteec.so → OP-TEE PKCS#11 TA → SE051 libckteec optee-client が提供するもので、OP-TEE PKCS#11 TAをバックエンドとしてCryptokiインターフェースを実装しています。TAはさらにOP-TEEのネイティブI2Cドライバを介して暗号処理をSE051にルーティングします。 必須ヘッダーとリンク #include /* 標準の Cryptoki ヘッダー — optee-client または OpenSC から */ コンパイルとリンク: gcc -o my_app my_app.c-ldl # または直接リンクしてください: gcc -o my_app my_app.c/usr/lib/libckteec.so.0 実行時に、動的ロードを使用する場合はモジュールパスを設定します。 #define PKCS11_MODULE "/usr/lib/libckteec.so.0" 初期化とトークン設定(起動時に一度だけ呼び出してください) #include #include #include #define CHECK_RV(RV、メッセージ)\ もし((RV)!= CKR_OK) { fprintf(stderr, "%s failed: 0x%lX\n", (msg), (rv)); goto cleanup; } /* ユーザーPIN — pkcs11-tool --init-pin */ static CK_UTF8CHAR user_pin[] = "1234"; 静的CK_ULONG user_pin_len = 4; CK_FUNCTION_LIST *p11 = NULL;/* グローバル関数リストポインタ */ CK_SESSION_HANDLE セッション = CK_INVALID_HANDLE; int pkcs11_init(void) { CK_RV rv; CK_ULONG slot_count = 0; CK_SLOT_ID slot_id; CK_SLOT_ID slot_list[8]; /* 関数リストの読み込み — 動的リンクを使用する場合、 C_GetFunctionList() */ rv = C_Initialize(NULL_PTR); CHECK_RV(rv, "C_Initialize"); /* 利用可能なスロットを獲得 */ rv = C_GetSlotList(CK_TRUE, NULL_PTR, &slot_count); CHECK_RV(rv, "C_GetSlotList (count)"); rv = C_GetSlotList(CK_TRUE, slot_list, &slot_count); CHECK_RV(rv, "C_GetSlotList"); slot_id = slot_list[0];/* 用途 最初のスロット — OP-TEE PKCS#11 TA */ /* 読み書きセッションを開く */ rv = C_OpenSession(slot_id, CKF_SERIAL_SESSION |CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session); CHECK_RV(rv, "C_OpenSession"); /* 通常ユーザーとしてログイン */ rv = C_Login(session, CKU_USER, user_pin, user_pin_len); CHECK_RV(rv、「C_Login」); 0を返す; クリーンアップ: 返却 -1; } void pkcs11_cleanup(void) { C_Logout(セッション); C_CloseSession(セッション); C_Finalize(NULL_PTR); } 操作1:RSA鍵ペアを生成し、SE051に保存する int generate_rsa_keypair(CK_OBJECT_HANDLE *pub_key, CK_OBJECT_HANDLE *priv_key) ヤージュ CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_ULONG キービット数 = 2048; CK_BYTE pub_exponent[] = { 0x01, 0x00, 0x01 }; /* 65537 */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; /* SE051 NVMに保存されるキーID — 一意の4バイトIDを選択してください */ CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_ATTRIBUTE pub_tmpl[] = { { CKA_MODULUS_BITS, &key_bits, sizeof(key_bits) }, { CKA_PUBLIC_EXPONENT, pub_exponent, sizeof(pub_exponent) }, { CKA_VERIFY, &ck_true, sizeof(ck_true) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_ID、key_id、sizeof(key_id) }、 }; CK_ATTRIBUTE priv_tmpl[] = { { CKA_SIGN, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID、key_id、sizeof(key_id) }、 }; rv = C_GenerateKeyPair(session, &mech, pub_tmpl、sizeof(pub_tmpl) / sizeof(pub_tmpl[0])、 priv_tmpl、sizeof(priv_tmpl) / sizeof(priv_tmpl[0])、 公開鍵、秘密鍵); CHECK_RV(rv, "C_GenerateKeyPair"); printf("RSA-2048キーペアが生成されました。秘密鍵はSE051 NVMに保存されます。\n"); 0を返す。 掃除: -1を返す。 } 操作2:SE051でAESキーとストアを生成する int generate_aes_key(CK_OBJECT_HANDLE *aes_key) { CK_RV rv; CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; CK_ULONG key_len = 32;/* 256ビットAES */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; CK_BYTE key_id[] = { 0x20, 0x00, 0x00, 0x01 }; CK_ATTRIBUTE aes_tmpl[] = { { CKA_VALUE_LEN, &key_len, sizeof(key_len) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID, key_id, sizeof(key_id) }, }; rv = C_GenerateKey(セッション、&mech、 aes_tmpl、sizeof(aes_tmpl) / sizeof(aes_tmpl[0]), aes_key); CHECK_RV(rv、「C_GenerateKey (AES)」)); printf("AES-256キーがSE051で生成・保存される");0を返す。 掃除: -1を返す。 } 操作3および4:AES-CBC暗号化/復号 int aes_encrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *plaintext, CK_ULONG plaintext_len, CK_BYTE *暗号文、CK_ULONG *暗号文の長さ) ヤージュ CK_RV rv; CK_BYTE iv[16] = { 0 }; /* 例:すべてゼロのIV。本番環境ではランダムなIVを使用してください */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_EncryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_EncryptInit"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, 暗号文、暗号文の長さ); CHECK_RV(rv, "C_Encrypt"); 0を返す。 掃除: -1を返す。 } int aes_decrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *ciphertext、CK_ULONG ciphertext_len、 CK_BYTE *プレーンテキスト、CK_ULONG *プレーンテキスト長) ヤージュ CK_RV rv; CK_BYTE iv[16] = { 0 }; /* 暗号化に使用されるIVと一致する必要があります */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_DecryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_DecryptInit"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, プレーンテキスト、プレーンテキストの長さ); CHECK_RV(rv, "C_Decrypt"); 0を返す。 掃除: -1を返す。 } 操作5および6:RSA署名(秘密鍵はSE051に保存)および検証 int rsa_sign(CK_OBJECT_HANDLE priv_key, const CK_BYTE *data, CK_ULONG data_len, CK_BYTE *署名、CK_ULONG *署名長) ヤージュ CK_RV rv; /* SHA256-PKCS1v1.5 — SE051 は内部で SHA-256 ダイジェストを計算してから署名します */ CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_SignInit(session, &mech, priv_key); CHECK_RV(rv, "C_SignInit"); rv = C_Sign(session, (CK_BYTE *)data, data_len, signature, sig_len); CHECK_RV(rv, "C_Sign"); printf("RSA署名が生成されました(%luバイト)。秘密鍵はSE051から一度も出ていません。*sig_len); 0を返す。 掃除: -1を返す。 } int rsa_verify(CK_OBJECT_HANDLE pub_key, const CK_BYTE *data, CK_ULONG data_len, const CK_BYTE *signature, CK_ULONG sig_len) ヤージュ CK_RV rv; CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_VerifyInit(session, &mech, pub_key); CHECK_RV(rv, "C_VerifyInit"); rv = C_Verify(session, (CK_BYTE *)data, data_len, (CK_BYTE *)署名、sig_len); if (rv == CKR_OK) { printf("署名検証:成功\n"); 0を返す。 } else if (rv == CKR_SIGNATURE_INVALID) { printf("署名検証: 無効\n"); 1を返す。 } CHECK_RV(rv, "C_Verify"); 掃除: -1を返す。 } 操作7と8:RSA暗号化/復号 int rsa_encrypt(CK_OBJECT_HANDLE pub_key, const CK_BYTE は *平文、CK_ULONG plaintext_len、 CK_BYTE *暗号文、CK_ULONG *ciphertext_len) { CK_RV rv; /* RSA-OAEP with SHA-256 — 新規設計にはPKCS1 v1.5より推奨 */ CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg= CKM_SHA256、 .mgf= CKG_MGF1_SHA256、 。ソース= CKZ_DATA_SPECIFIED、 .pSourceData= NULL、 .ulSourceDataLen= 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_EncryptInit(session, &mech, pub_key); CHECK_RV(rv, "C_EncryptInit (RSA-OAEP)"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, 暗号文、暗号文の長さ); CHECK_RV(rv, "C_Encrypt (RSA-OAEP)"); 0を返す。 掃除: -1を返す。 } int rsa_decrypt(CK_OBJECT_HANDLE priv_key, const CK_BYTE *ciphertext、CK_ULONG ciphertext_len、 CK_BYTE *プレーンテキスト、CK_ULONG *プレーンテキスト長) ヤージュ CK_RV rv; CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg= CKM_SHA256、 .mgf= CKG_MGF1_SHA256、 。ソース= CKZ_DATA_SPECIFIED、 .pSourceData= NULL、 .ulSourceDataLen= 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_DecryptInit(session, &mech, priv_key); CHECK_RV(rv, "C_DecryptInit (RSA-OAEP)"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, プレーンテキスト、プレーンテキストの長さ); CHECK_RV(rv, "C_Decrypt (RSA-OAEP)"); printf("RSA復号化が完了しました。秘密鍵はSE051から一度も出ていません。\n");0を返す。 掃除: -1を返す。 } 既存キーへのアクセス(再生成なし) 鍵が以前に生成され、SE051に保存されている場合は、 C_GenerateKey を再度呼び出すことなく、CKA_IDを使用して鍵を取得します。 int find_key_by_id(CK_BYTE *key_id, CK_ULONG key_id_len, CK_OBJECT_CLASS obj_class、 CK_OBJECT_HANDLE *ハンドル) ヤージュ CK_RV rv; CK_ULONG obj_count = 0; CK_ATTRIBUTE search_tmpl[] = { { CKA_CLASS, &obj_class, sizeof(obj_class) }, { CKA_ID、key_id、key_id_len }、 }; rv = C_FindObjectsInit(session, search_tmpl, sizeof(search_tmpl) / sizeof(search_tmpl[0])); CHECK_RV(rv, "C_FindObjectsInit"); rv = C_FindObjects(session, handle, 1, &obj_count); CHECK_RV(rv, "C_FindObjects"); C_FindObjectsFinal(session); if (obj_count == 0) { fprintf(stderr, "キーがSE051で見つかりません\n"); -1を返す。 } 0を返す。 掃除: C_FindObjectsFinal(session); -1を返す。 } 使用例: CK_OBJECT_HANDLE プライベートキー; CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_OBJECT_CLASS priv_class = CKO_PRIVATE_KEY; find_key_by_id(key_id, sizeof(key_id), priv_class, &priv_key); 対応メカニズム(OP-TEE PKCS#11 TA + SE051で検証済み) 動作 機構定数 備考 RSA鍵生成 CKM_RSA_PKCS_KEY_PAIR_GEN 256~4096ビット AESキー生成 CKM_AES_KEY_GEN 16バイトまたは32バイト RSA署名/検証 CKM_SHA256_RSA_PKCS PKCS#1 v1.5 RSA署名/検証(PSS) CKM_SHA256_RSA_PKCS_PSS PSSパディング RSA暗号化/復号化 CKM_RSA_PKCS_OAEP OAEP推奨 RSA暗号化/復号化 CKM_RSA_PKCS PKCS#1 v1.5 AESの暗号化/復号 CKM_AES_CBC_PAD CBCとPKCS#7 AESの暗号化/復号 CKM_AES_CBC パディングなしのCBC AESの暗号化/復号 CKM_AES_CTR CTRモード ECC署名/検証 CKM_ECDSA_SHA256 160~521ビット ECDHの主要合意 CKM_ECDH1_DERIVE   SSS APIはそもそも使えますか? はい、ただし共 存環境(オプション2 )でのみ、LinuxがI2Cバスにアクセスできる場合(つまり lf-6.12.y-i2c-disabled-se050 DTSパッチが適用されていない場合)。その場合、AN13030セクション3.3に説明されているSSS APIをLinuxから直接利用できます。 オプション1(OP-TEE専用)を選択すると、上記のCryptoki/PKCS#11 C APIがLinuxユーザースペースからの正確かつ唯一サポートされている経路です。 参照 AN13030 Rev. 2.4、セクション3.3 — SSS APIの完全リファレンス(共存/非OP-TEEビルド用) OP-TEE PKCS#11 TAテストスイート(pkcs11_1000.c): optee-test/host/xtest/pkcs11_1000.c — Cryptoki のすべての操作に関する包括的な C 言語の例 NXP GitHub: se05x-pkcs11 — NXPのPKCS#11スタンドアロンライブラリ(OP-TEE以外のビルドでは libckteec.so 代替として使用可能)   お役に立てば幸いです。   すてきな一日を、 カン ------------------------------------------------------------------------------- 注記: この投稿があなたの質問への回答になっている場合は、「正解としてマーク」ボタンをクリックしてください。ありがとうございます! - 前回の投稿から7週間Threadをフォローしており、その後の返信は無視しています もし後で関連する質問があれば、新しいThreadを開き、閉じたThreadを参照してください。 ------------------------------------------------------------------------------- Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li 分かりやすく詳細なご説明をありがとうございました。 現在、将来の開発段階に応じてオプション1かオプション2の使用を検討しています(例:初期テスト・評価にオプション2、本番にオプション1を使う)。 オプション1(OP-TEE PKCS#11 TA)についてですが、C言語でのアプリケーション開発に関する質問があります。 オプション1に従って、鍵の保存、署名/署名生成、署名検証、暗号化/復号化などの暗号化操作をCプログラムで実装する場合、どの方法を採用すべきでしょうか? 標準的なPKCS#11 API(例:C_Initialize、C_CreateObject、C_SignInit、C_Sign、C_VerifyInit、C_Verifyなど)をOP-TEEのPKCS#11ライブラリ(libckteec.so)経由で直接呼び出すCプログラムを書くべきでしょうか? あるいは、この設定でもPlug & Trust MW SSS API(sss_key_store_set_key、sss_asymmetric_sign_digest、sss_asymmetric_verify_digest、sss_cipher_updateなど)を使用することは可能/推奨されますか? もしPKCS#11 APIが必要な場合、Cで libckteec.so を呼び出すための簡単なサンプルコードや参考ガイドを教えていただけますか? Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment こんにちは、 @Uc_S さん、 詳細な報告をありがとうございました。根本原因は明確で、なぜこうなるのか、そしてどんな選択肢があるのかを正確に説明します。 根本的な原因 se05x_Minimal -DPTMW_SMCOM=T1oI2C で構築されました。これにより、smComレイヤーはセッションオープン時に物理的なLinux I2Cデバイスノード( /dev/i2c-X )を開くよう指示されます。 lf-6.12.y-i2c-disabled-se050 DTSパッチ(統合ガイドのステップ1)を適用したため、Linux Normal WorldではそのI2Cコントローラが無効化されており、デバイスノード自体が存在しません。OP-TEEは CFG_IMX_I2C=y を通じてI2Cバスを独占的に所有しており、Linuxはそれを認識したり開いたりできません。 これは意図的なもので 、DTSパッチがOP-TEEにSE051への独占的かつ無競争のアクセス権を与えるものです。 T1oI2C で構築された se05x_Minimal バイナリは、この構成と根本的に互換性がありません。 あなたの2つの選択肢 ✅ オプション1 — OP-TEE PKCS#11 TAを使用する(生産用途に推奨) これはOP-TEE独占セットアップにおけるLinuxユーザースペースの意図パスです。 se05x_Minimal を実行する代わりに、 pkcs11-tool またはOpenSSLと libckteec.so (OP-TEE PKCS#11 TAライブラリ)を使用してください。TAは内部的にSE051を暗号バックエンドとして、OP-TEEのネイティブI2Cドライバを介して使用しています。 SE051がPKCS#11経由で到達可能であることを簡単に検証します。 # List available PKCS#11 slots — SE051 should appear pkcs11-tool --module /usr/lib/libckteec.so.0 --list-slots # Get a random number from SE051 via OP-TEE pkcs11-tool --module /usr/lib/libckteec.so.0 --generate-random 16 | xxd スロットとランダムなバイト列が表示されている場合、SE051はOP-TEEを介して完全にアクセス可能です。 se05x_Minimal を実行する必要はありません。PKCS#11 TAが既に提供している機能と重複しています。 ✅ オプション2 — 共存環境の構築(開発/テストに推奨) Linuxユーザースペースから se05x_Minimal やその他のPlug & Trust MWデモを実行する必要がある場合は、Linux DTSがI2Cを有効にしたまま共 存する環境 (つまり、I2C無効のDTSパッチを適用 しない )を用いてください。 手順: ステップ1 — 通常世界でI2Cを有効にし続けるためにLinux DTSを元に戻す lf-6.12.y-i2c-disabled-se050 パッチなしで、未改変のLinux DTSから imx8mq-evk.dtb (または同等のもの)を構築しましょう。SE051のI2CコントローラノードはLinux上で有効化されたままである必要があります。 ステップ2 — 既存のcmakeフラグは変更しない 現在のcmakeの設定は共存環境において正しいです。 cmake -S . -B ./build/ -DPTMW_Applet=SE05X_C -DPTMW_SE05X_Ver=07_02 -DPTMW_Host=iMXLinux -DPTMW_SMCOM=T1oI2C -DPTMW_HostCrypto=OPENSSL -DPTMW_RTOS=Default -DPTMW_mbedTLS_ALT=None -DPTMW_SCP=SCP03_SSS -DPTMW_SE05X_Auth=PlatfSCP03 -DPTMW_Log=Silent -DCMAKE_BUILD_TYPE=Release -DPTMW_OpenSSL=3_0 -DPTMW_SE_RESET_LOGIC=1 ステップ3 — 実行前にI2Cポートを設定する export EX_SSS_BOOT_SSS_PORT=/dev/i2c-1 ./se05x_Minimal トレードオフ: このモードでは、OP-TEEとLinuxの両方がSE051へのI2Cバスを共有します。OP-TEEはRSA/ECCオフロードに使っています。LinuxはMWデモに使っています。同時アクセスは仲裁されず、負荷時にAPDUの衝突が発生することがあります。開発用途には許容範囲内だが、製品版での使用は推奨しない。 概要 オプション I2C DTS se05x_ミニマル OP-TEE限定 おすすめ対象 PKCS#11 TA ( libckteec.so ) ディセーブルされる ❌ 不要 ✅ はい 量産 共存(T1oI2C) イネーブル ✅ 作品 ⚠️ 共有I2C 開発/テスト 統合ガイドに関する説明 あなたが参照したコミュニティ投稿(ステップ2 - CAAMなし)では、OP-TEEがI2Cを独占的に所有するように設定されています。そのガイドに示されたLinux側のMWコンパイル( T1oI2C 付き)は、OP-TEEモードに切り替える前の 初期検証ステップ として意図されており、OP-TEE専用のI2Cセットアップと併用するものではありません。 OP-TEEがI2Cを独占的に所有すると、正しいLinuxユーザースペースインターフェースは OP-TEE PKCS#11 TAであり、Plug & Trust MW SSS APIデモ自体ではありません。 どの選択肢があなたのユースケースに合っているか教えていただければ、さらなるアドバイスを提供できます。 すてきな一日を、 カン ------------------------------------------------------------------------------- 注記: この投稿があなたの質問への回答になっている場合は、「正解としてマーク」ボタンをクリックしてください。ありがとうございます! - 前回の投稿から7週間Threadをフォローしており、その後の返信は無視しています もし後で関連する質問があれば、新しいThreadを開き、閉じたThreadを参照してください。 -------------------------------------------------------------------------------
View full article
使用 s32k144 MBD 工具箱进行 I2C 读写 你好, 我正在使用 s32k144 从外部 EEPROM 读取和写入数据。我将在下面附上模型。我可以写入数据,但读取操作返回 255+NACK 作为输出。我是不是漏掉了什么? Sriram_0-1737789999186.pngSriram_0-1737789999186.png Sriram_1-1737790013461.pngSriram_1-1737790013461.png 是否有办法在 I2Cmaster 模块中指定 EEPROM 的寄存器地址? Sriram_2-1737790096449.pngSriram_2-1737790096449.png 各位能帮我解决这个问题吗? 谢谢 Re: I2C read and write using s32k144 MBD toolbox 您好, 我也遇到了同样的问题,在使用S32K144作为主设备, ST M24C04 EEPROM作为从设备进行 I2C 通信时,出现了问题。 由于你们使用的是相同的微控制器和 EEPROM,我想确认一下你们是否找到了解决方案。如果您已经解决了这个问题,能否分享一下解决方案或者告诉我是什么方法解决了这个问题? 提前感谢您的帮助。 Re: I2C read and write using s32k144 MBD toolbox 我使用的是 M24C02-DRE EEPROM
View full article
寻求指导:se05x_Minimal 在 OP-TEE 环境中失败 NXP社区的各位朋友,大家好! 我正在尝试在运行 Linux 和 OP-TEE 的目标板上运行 se05x_Minimal。 根据这篇社区帖子(如何将 Plug and Trust MW 集成到 OP-TEE 中)中推荐的解决方案,我们相应地构建了环境。 具体来说,对于步骤 2,我们在配置设置时没有启用“保持 CAAM 启用”选项。 由于这种配置,连接到 SE05x 的 I2C 总线由 OP-TEE(安全世界)管理,标准的 Linux I2C 设备节点 /dev/i2c-1 在普通世界(Linux)中不可见/不可用。 当直接从 Linux 用户空间控制台执行 `./se05x_Minimal` 时,会遇到以下错误: App :INFO :Running ./se05x_Minimal App :INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments. App :INFO :PlugAndTrust_v04.07.01_20250519 App :INFO :Using default PlatfSCP03 keys. You can use keys from file using ENV=EX_SSS_BOOT_SCP03_PATH smCom :ERROR:opening failed... Failed to open the i2c bus: No such file or directory smCom :INFO :Pass i2c device address in the format : . smCom :INFO :Example ./example /dev/i2c-1:0x48 OR ./example /dev/i2c-1 smCom :ERROR:phPalEse_i2c_open_and_configure Failed retry smCom :ERROR:I2C init Failed: retval d smCom :ERROR:phPalEse_Init Failed smCom :ERROR: Failed to create physical connection with ESE sss :ERROR:SM_I2CConnect Failed. Status 7012 App :ERROR:sss_session_open failed App :ERROR:ex_sss_session_open Failed App :ERROR:!ERROR! ret != 0. 环境及硬件设置:评估板:MCIMX8M-WEVK(i.MX 8M 双核/四核) 安全元件板:OM-SE051ARD 安全元件:SE05x(Plug & Trust MW v04.07.01) 操作系统:Linux(普通环境)+ OP-TEE(安全环境) 中间件选项(CMake):-DPTMW_Host=iMXLinux,-DPTMW_SMCOM=T1oI2C 注意:如果启用了 Linux 内核空间直接 I2C (/dev/i2c-1),则 se05x_Minimal 可以正常工作。 smCom 似乎仍在尝试打开物理 Linux I2C 设备 (/dev/i2c-X),该设备在我们的正常世界环境中已不存在。 请问能否提供一些说明,告诉我们需要进行哪些操作或修改,才能使 se05x_Minimal 在此设置下成功运行? SE050 Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li 非常感谢您的详细解释和提供的C代码示例。 按照您的指导,我们使用标准 PKCS#11 API (libckteec.so.0) 在选项 1 (OP-TEE 独占 I2C 设置) 下实现了一个 C 应用程序。 所有操作——包括密钥生成、AES 加密/解密、RSA 签名/验证和 RSA 加密/解密——现在都完全按预期运行。 感谢您对解决此问题的支持。 Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment 嗨@Uc_S , 这是一个非常好的重要问题。简而言之: 在选项 1(OP-TEE 专用 I2C)中,Plug & Trust MW SSS API 不能直接从 Linux 用户空间使用。您必须通过 libckteec.so 使用标准的 PKCS#11 C API。 下面提供了所有必要操作的详细说明和完整的 C 代码示例。 为什么在此设置中无法使用 SSS API Plug & Trust MW SSS API( sss_session_open 、 sss_key_store_set_key 、 sss_asymmetric_sign_digest 等)依赖于传输层与 SE051 通信。所有受支持的传输( T1oI2C 、 JRCP_V1_AM 等)最终都需要 Linux I2C 访问或代理服务器——当 OP-TEE 独占 I2C 总线时,这两者都不可用。 OP-TEE 独占设置中的正确路径是: Your C App → PKCS#11 C API (cryptoki.h) → libckteec.so → OP-TEE PKCS#11 TA → SE051 libckteec 由 optee-client 提供,并以 OP-TEE PKCS#11 TA 作为其后端实现 Cryptoki 接口。TA 进而通过 OP-TEE 的原生 I2C 驱动程序将加密操作路由到 SE051。 必需的标头和链接 #include /* 标准 Cryptoki 标头 — 来自 optee-client 或 OpenSC */ 编译和链接: gcc -o my_app my_app.c-ldl 或者直接链接: gcc -o my_app my_app.c/usr/lib/libckteec.so.0 如果使用动态加载,则在运行时设置模块路径: #define PKCS11_MODULE "/usr/lib/libckteec.so.0" 初始化和令牌设置(启动时调用一次) #include #include #include #define CHECK_RV(rv, msg) \ 如果 ((rv) != CKR_OK) { fprintf(stderr, "%s 失败:0x%lX\n", (msg), (rv)); goto cleanup; } /* 用户 PIN 码 — 必须与使用 pkcs11-tool --init-pin 设置的 PIN 码一致 */ static CK_UTF8CHAR user_pin[] = "1234"; 静态CK_ULONG user_pin_len = 4; CK_FUNCTION_LIST *p11 = NULL; /* 全局函数列表指针 */ CK_SESSION_HANDLE session = CK_INVALID_HANDLE; int pkcs11_init(void) { CK_RV rv; CK_ULONG slot_count = 0; CK_SLOT_ID 插槽 ID; CK_SLOT_ID slot_list[8]; /* 加载函数列表 — 如果使用动态链接,请使用 C_GetFunctionList() */ rv = C_Initialize(NULL_PTR); CHECK_RV(rv, "C_Initialize"); /* 获取可用槽位 */ rv = C_GetSlotList(CK_TRUE, NULL_PTR, &slot_count); CHECK_RV(rv, "C_GetSlotList (count)"); rv = C_GetSlotList(CK_TRUE, slot_list, &slot_count); CHECK_RV(rv, "C_GetSlotList"); slot_id = slot_list[0]; /* 使用第一个槽位 — OP-TEE PKCS#11 TA */ /* 打开读写会话 */ rv = C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR、NULL_PTR、&session); CHECK_RV(rv, "C_OpenSession"); /* 以普通用户身份登录 */ rv = C_Login(session, CKU_USER, user_pin, user_pin_len); CHECK_RV(rv, "C_Login"); 返回 0; 清理: 返回 -1; } void pkcs11_cleanup(void) { C_Logout(session); C_CloseSession(session); C_Finalize(NULL_PTR); } 操作 1:生成 RSA 密钥对并存储在 SE051 中 int generate_rsa_keypair(CK_OBJECT_HANDLE *pub_key, CK_OBJECT_HANDLE *priv_key) { CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_ULONG 密钥位数 = 2048; CK_BYTE pub_exponent[] = { 0x01, 0x00, 0x01 }; /* 65537 */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; /* 密钥 ID 存储在 SE051 NVM 中 — 选择一个唯一的 4 字节 ID */ CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_ATTRIBUTE pub_tmpl[] = { { CKA_MODULUS_BITS, &key_bits, sizeof(key_bits) }, { CKA_PUBLIC_EXPONENT, pub_exponent, sizeof(pub_exponent) }, { CKA_VERIFY, &ck_true, sizeof(ck_true) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_ID, key_id, sizeof(key_id) }, }; CK_ATTRIBUTE priv_tmpl[] = { { CKA_SIGN, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID, key_id, sizeof(key_id) }, }; rv = C_GenerateKeyPair(session, &mech, pub_tmpl,sizeof(pub_tmpl) / sizeof(pub_tmpl[0]), priv_tmpl, sizeof(priv_tmpl) / sizeof(priv_tmpl[0]), 公钥,私钥); CHECK_RV(rv, "C_GenerateKeyPair"); printf("RSA-2048 密钥对已生成。私钥保存在 SE051 NVM 中。\n"); 返回 0; 清理: 返回 -1; } 操作 2:生成 AES 密钥并存储在 SE051 中 int generate_aes_key(CK_OBJECT_HANDLE *aes_key) { CK_RV rv; CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; CK_ULONG key_len = 32; /* 256 位 AES */ CK_BBOOL ck_true = CK_TRUE; CK_BBOOL ck_false = CK_FALSE; CK_BYTE key_id[] = { 0x20, 0x00, 0x00, 0x01 }; CK_ATTRIBUTE aes_tmpl[] = { { CKA_VALUE_LEN, &key_len, sizeof(key_len) }, { CKA_ENCRYPT, &ck_true, sizeof(ck_true) }, { CKA_DECRYPT, &ck_true, sizeof(ck_true) }, { CKA_TOKEN, &ck_true, sizeof(ck_true) }, { CKA_SENSITIVE, &ck_true, sizeof(ck_true) }, { CKA_EXTRACTABLE, &ck_false, sizeof(ck_false) }, { CKA_ID, key_id, sizeof(key_id) }, }; rv = C_GenerateKey(session, &mech, aes_tmpl,sizeof(aes_tmpl) / sizeof(aes_tmpl[0]), aes_key); CHECK_RV(rv, "C_GenerateKey (AES)"); printf("AES-256密钥已生成并存储在SE051中。\n");返回 0; 清理: 返回 -1; } 操作 3 和 4:AES-密码块链接(CBC) 加密/解密 int aes_encrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *plaintext, CK_ULONG plaintext_len, CK_BYTE *密文,CK_ULONG *密文长度) { CK_RV rv; CK_BYTE iv[16] = { 0 }; /* 示例:全零 IV;生产环境中使用随机 IV */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_EncryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_EncryptInit"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, 密文,密文长度); CHECK_RV(rv, "C_Encrypt"); 返回 0; 清理: 返回 -1; } int aes_decrypt(CK_OBJECT_HANDLE aes_key, const CK_BYTE *ciphertext, CK_ULONG ciphertext_len, CK_BYTE *plaintext, CK_ULONG *plaintext_len) { CK_RV rv; CK_BYTE iv[16] = { 0 }; /* 必须与加密所用的 IV 匹配 */ CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, sizeof(iv) }; rv = C_DecryptInit(session, &mech, aes_key); CHECK_RV(rv, "C_DecryptInit"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, 纯文本,纯文本长度); CHECK_RV(rv, "C_Decrypt"); 返回 0; 清理: 返回 -1; } 操作 5 和 6:RSA 签名(私钥保留在 SE051 中)和验证 int rsa_sign(CK_OBJECT_HANDLE priv_key, const CK_BYTE *data, CK_ULONG data_len, CK_BYTE *签名,CK_ULONG *签名长度) { CK_RV rv; /* 安全散列算法(SHA)256-PKCS1v1.5 — SE051 在内部计算 安全散列算法(SHA)-256 摘要,然后进行签名 */ CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_SignInit(session, &mech, priv_key); CHECK_RV(rv, "C_SignInit"); rv = C_Sign(session, (CK_BYTE *)data, data_len, signature, sig_len); CHECK_RV(rv, "C_Sign"); printf("RSA 签名已生成(%lu 字节)。私钥从未离开过 SE051。\n",*sig_len); 返回 0; 清理: 返回 -1; } int rsa_verify(CK_OBJECT_HANDLE pub_key, const CK_BYTE *data, CK_ULONG data_len, const CK_BYTE *signature, CK_ULONG sig_len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 }; rv = C_VerifyInit(session, &mech, pub_key); CHECK_RV(rv, "C_VerifyInit"); rv = C_Verify(session, (CK_BYTE *)data, data_len, (CK_BYTE *)签名,sig_len); 如果 (rv == CKR_OK) { printf("签名验证:成功\n"); 返回 0; } 否则如果 (rv == CKR_SIGNATURE_INVALID) { printf("签名验证:无效\n"); 返回 1; } CHECK_RV(rv, "C_Verify"); 清理: 返回 -1; } 操作 7 和 8:RSA 加密/解密 int rsa_encrypt(CK_OBJECT_HANDLE pub_key, const CK_BYTE *plaintext, CK_ULONG plaintext_len, CK_BYTE *密文,CK_ULONG *密文长度) { CK_RV rv; /* RSA-OAEP with SHA-256 — 建议在新设计中使用,而非 PKCS1 v1.5 */ CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg= CKM_SHA256, .mgf= CKG_MGF1_SHA256, 。来源= CKZ_DATA_SPECIFIED, .pSourceData= NULL, .ulSourceDataLen= 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_EncryptInit(session, &mech, pub_key); CHECK_RV(rv, "C_EncryptInit (RSA-OAEP)"); rv = C_Encrypt(session, (CK_BYTE *)plaintext, plaintext_len, 密文,密文长度); CHECK_RV(rv, "C_Encrypt (RSA-OAEP)"); 返回 0; 清理: 返回 -1; } int rsa_decrypt(CK_OBJECT_HANDLE priv_key, const CK_BYTE *ciphertext, CK_ULONG ciphertext_len, CK_BYTE *plaintext, CK_ULONG *plaintext_len) { CK_RV rv; CK_RSA_PKCS_OAEP_PARAMS oaep_params = { .hashAlg= CKM_SHA256, .mgf= CKG_MGF1_SHA256, 。来源= CKZ_DATA_SPECIFIED, .pSourceData= NULL, .ulSourceDataLen= 0 }; CK_MECHANISM mech = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) }; rv = C_DecryptInit(session, &mech, priv_key); CHECK_RV(rv, "C_DecryptInit (RSA-OAEP)"); rv = C_Decrypt(session, (CK_BYTE *)ciphertext, ciphertext_len, 纯文本,纯文本长度); CHECK_RV(rv, "C_Decrypt (RSA-OAEP)"); printf("RSA 解密完成。"私钥从未离开 SE051。\n");返回 0; 清理: 返回 -1; } 访问现有密钥(无需重新生成) 如果密钥之前已生成并存储在 SE051 中,则通过 CKA_ID 检索该密钥,而无需再次调用 C_GenerateKey : int find_key_by_id(CK_BYTE *key_id, CK_ULONG key_id_len, CK_OBJECT_CLASS obj_class, CK_OBJECT_HANDLE *handle) { CK_RV rv; CK_ULONG obj_count = 0; CK_ATTRIBUTE search_tmpl[] = { { CKA_CLASS, &obj_class, sizeof(obj_class) }, { CKA_ID, key_id, key_id_len }, }; rv = C_FindObjectsInit(session, search_tmpl, sizeof(search_tmpl) / sizeof(search_tmpl[0])); CHECK_RV(rv, "C_FindObjectsInit"); rv = C_FindObjects(session, handle, 1, &obj_count); CHECK_RV(rv, "C_FindObjects"); C_FindObjectsFinal(session); 如果 (obj_count == 0) { fprintf(stderr, "在 SE051 中未找到密钥\n"); 返回 -1; } 返回 0; 清理: C_FindObjectsFinal(session); 返回 -1; } 使用示例: CK_OBJECT_HANDLE priv_key; CK_BYTE key_id[] = { 0x10, 0x10, 0x10, 0x10 }; CK_OBJECT_CLASS priv_class = CKO_PRIVATE_KEY; find_key_by_id(key_id, sizeof(key_id), priv_class, &priv_key); 支持的机制(已在 OP-TEE PKCS#11 TA + SE051 上验证) Operation 机制常数 说明 RSA密钥生成 CKM_RSA_PKCS_KEY_PAIR_GEN 256–4096 位 AES密钥生成 CKM_AES_KEY_GEN 16 或 32 字节 RSA签名/验证 CKM_SHA256_RSA_PKCS PKCS#1 v1.5 RSA 签名/验证 (PSS) CKM_SHA256_RSA_PKCS_PSS PSS 填充 RSA 加密/解密 CKM_RSA_PKCS_OAEP OAEP推荐 RSA 加密/解密 CKM_RSA_PKCS PKCS#1 v1.5 AES 加密/解密 CKM_AES_CBC_PAD 密码块链接\(CBC\) 与 PKCS#7 AES 加密/解密 CKM_AES_CBC 无衬垫的密码块链接(CBC) AES 加密/解密 CKM_AES_CTR CTR模式 ECC签名/验证 CKM_ECDSA_SHA256 160–521 位 ECDH关键协议 CKM_ECDH1_DERIVE   SSS API 还能继续使用吗? 是的——但仅限于共存设置(选项 2) ,其中 Linux 仍然可以访问 I2C 总线(即,尚未应用 lf-6.12.y-i2c-disabled-se050 DTS 补丁)。在这种情况下,您可以直接从 Linux 使用 AN13030 第 3.3 节中描述的 SSS API。 如果您选择选项 1(OP-TEE 专属),则上面显示的 Cryptoki/PKCS#11 C API 是 Linux 用户空间中正确且唯一支持的路径。 参考 AN13030 Rev. 2.4,第 3.3 节 — 完整的 SSS API 参考(适用于共存/非 OP-TEE 构建) OP-TEE PKCS#11 TA 测试套件 (pkcs11_1000.c): optee-test/host/xtest/pkcs11_1000.c — 所有 Cryptoki 操作的完整 C 示例 NXP GitHub: se05x-pkcs11 — NXP 的 PKCS#11 独立组网 (SA) 库(非 OP-TEE 版本的 libckteec.so 替代方案)   希望对您有所帮助。   祝你有美好的一天, 坎 ------------------------------------------------------------------------------- 笔记: - 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你! - 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。 如果您之后有相关问题,请另开新帖并引用已关闭的帖子。 ------------------------------------------------------------------------------- Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment @Kan_Li 非常感谢您清晰详细的解释。 我们目前正在考虑根据未来发展的阶段选择方案 1 或方案 2(例如,使用方案 2 进行初步测试/评估,使用方案 1 进行生产)。 关于选项 1(OP-TEE PKCS#11 TA),我们有一个关于 C 语言应用程序开发的问题。 如果要在方案 1 下用 C 程序实现密钥存储、签名/签名生成、签名验证和加密/解密等加密操作,我们应该采取哪种方法? 我们是否应该编写一个 C 程序,通过 OP-TEE PKCS#11 库 (libckteec.so) 直接调用标准 PKCS#11 API(例如 C_Initialize、C_CreateObject、C_SignInit、C_Sign、C_VerifyInit、C_Verify 等)? 或者,在这种设置下是否仍然可以/建议使用 Plug & Trust MW SSS API(例如 sss_key_store_set_key、sss_asymmetric_sign_digest、sss_asymmetric_verify_digest、sss_cipher_update 等)? 如果需要使用 PKCS#11 API,能否提供一个简单的示例代码或参考指南,说明如何在 C 语言中调用 libckteec.so? Re: Seeking guidance: se05x_Minimal fails in OP-TEE environment 嗨@Uc_S , 感谢您提供的详细报告。根本原因很明确,我可以详细解释为什么会发生这种情况以及你有哪些选择。 根本原因 se05x_Minimal 由 -DPTMW_SMCOM=T1oI2C 构建。这告诉 smCom 层在会话打开时打开一个物理 Linux I2C 设备节点 ( /dev/i2c-X )。由于您应用了 lf-6.12.y-i2c-disabled-se050 DTS 补丁(集成指南的步骤 1),该 I2C 控制器在 Linux 正常世界中被禁用——设备节点根本不存在。OP-TEE 通过 CFG_IMX_I2C=y 独家拥有 I2C 总线,Linux 无法看到或打开它。 这是有意为之——DTS 补丁使 OP-TEE 能够独占、不受竞争地访问 SE051。使用 T1oI2C 构建的 se05x_Minimal 二进制文件与此配置根本不兼容。 你的两个选择 ✅ 方案 1 — 使用 OP-TEE PKCS#11 TA(推荐用于生产) 这是 OP-TEE 独占设置中预期的 Linux 用户空间路径。不要运行 se05x_Minimal ,而是使用 pkcs11-tool 或 OpenSSL 和 libckteec.so (OP-TEE PKCS#11 TA 库)。TA 内部使用 SE051 作为其加密后端,通过 OP-TEE 的原生 I2C 驱动程序。 快速验证 SE051 是否可通过 PKCS#11 访问: # List available PKCS#11 slots — SE051 should appear pkcs11-tool --module /usr/lib/libckteec.so.0 --list-slots # Get a random number from SE051 via OP-TEE pkcs11-tool --module /usr/lib/libckteec.so.0 --generate-random 16 | xxd 如果看到一个插槽和随机字节,则 SE051 可通过 OP-TEE 完全访问。无需运行 se05x_Minimal – 它重复了 PKCS#11 TA 已经提供的功能。 ✅ 选项 2 — 共存设置(推荐用于开发/测试) 如果您需要从 Linux 用户空间运行 se05x_Minimal 和其他 Plug & Trust MW 演示程序,请使用共存设置,其中 Linux DTS 仍然启用 I2C(即,不要应用禁用 I2C 的 DTS 补丁)。 步骤: 步骤 1 — 恢复 Linux DTS 以在普通世界中保持 I2C 启用状态 从未经修改的Linux DTS(不带 lf-6.12.y-i2c-disabled-se050 补丁)构建您的 imx8mq-evk.dtb (或等效版本)。SE051 的 I2C 控制器节点必须在 Linux 系统中保持启用状态。 步骤 2 — 保持现有 CMake 标志不变 您当前的 cmake 配置对于共存模式是正确的: cmake -S . -B ./build/ -DPTMW_Applet=SE05X_C -DPTMW_SE05X_Ver=07_02 -DPTMW_Host=iMXLinux -DPTMW_SMCOM=T1oI2C -DPTMW_HostCrypto=OPENSSL -DPTMW_RTOS=Default -DPTMW_mbedTLS_ALT=None -DPTMW_SCP=SCP03_SSS -DPTMW_SE05X_Auth=PlatfSCP03 -DPTMW_Log=Silent -DCMAKE_BUILD_TYPE=Release -DPTMW_OpenSSL=3_0 -DPTMW_SE_RESET_LOGIC=1 步骤 3 — 运行前设置 I2C 端口 export EX_SSS_BOOT_SSS_PORT=/dev/i2c-1 ./se05x_Minimal 权衡:在这种模式下,OP-TEE 和 Linux 都共享到 SE051 的 I2C 总线。OP-TEE 将其用于 RSA/ECC 卸载;Linux 将其用于 MW 演示。并发访问不进行仲裁,这可能导致负载过高时发生 APDU 冲突。适用于开发,但不建议用于生产。 摘要 选项 I2C DTS se05x_Minimal OP-TEE独家 推荐用于 PKCS#11 TA ( libckteec.so ) 禁用 ❌ 不需要 ✅ 是 已量产 共存(T1oI2C) 已启用 ✅ 作品 ⚠️ 共享 I2C 开发/测试 关于集成指南的说明 您引用的社区帖子(步骤 2 — 不使用 CAAM)将 OP-TEE 配置为独占 I2C。该指南中显示的 Linux 端 MW 编译(带有 T1oI2C )旨在用于切换到 OP-TEE 模式之前的初始验证步骤,而不是与 OP-TEE 专用 I2C 设置一起使用。 一旦 OP-TEE 完全拥有 I2C,正确的 Linux 用户空间接口就是OP-TEE PKCS#11 TA ,而不是 Plug & Trust MW SSS API 演示。 请与我们联系哪个选项最符合您的使用场景,我们将提供进一步的指导。 祝你有美好的一天, 坎 ------------------------------------------------------------------------------- 笔记: - 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你! - 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。 如果您之后有相关问题,请另开新帖并引用已关闭的帖子。 -------------------------------------------------------------------------------
View full article
S32DS for ARM 2018.R1 debug Problem S32DS for ARM 2018.R1 have a problem when I debug S32K146 chip, As follow: Could not determine GDB version after sending: D:\S32DS\eclipse\../Cross_Tools/gcc-arm-none-eabi-4_9/bin/arm-none-eabi-gdb --version, response: But, Jlink can cnonect and erase and program chip. Now, I do not debug using S32DS for ARM 2018.R1, Please help me, Thanks! Re: S32DS for ARM 2018.R1 debug Problem Hi@lyz I didn't quite understand your question. Could you post a screenshot of the error?
View full article
i.MX93 M33 无法使用系统 TCM RAM 进行分配 我们正在评估 i.MX9352 在物联网设备中的应用。我为 M33 内核创建了一个应用程序,用于执行时间关键型 IO 操作,其中包括从外围设备收集大量样本。为了开发目的,我正在使用 remoteproc 从 Linux 加载和启动 M33 代码。代码是用 C 语言编写的,并使用了 MPUXpresso 26.06.00 SDK。 代码运行良好,但我现在需要一个大的样本缓冲区(约 24 kB)。我尝试过将其添加为静态数组或使用 `malloc` 分配的堆。无论哪种情况,我的内存似乎都会耗尽,即使编译输出表明内存充足。 工作版本: 以下是使用较小缓冲区版本的内存信息,**运行正常**(但缓冲区太小,无法满足我们的要求)。 Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78300 B 129928 B 60.26% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 48016 B 108 KB 43.42% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. 以下是ELF文件中的一些信息: readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131dc 0x131dc RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3654 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37e0 0x00000 0x0ba10 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack 大型静态分配: 以下是使用 **24 kB 静态分配缓冲区**的编译版本的内存和 ELF 文件信息。 IE。: static uint32_t m_sample_queue[SAMPLE_QUEUE_LENGTH]; // SAMPLE_QUEUE_LENGTH = 6000 Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 72016 B 108 KB 65.12% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. ### (As expected, the `m_data` section has increased in size.) ### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x117d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack 当我在 Linux 系统中尝试使用 remoteproc 启动此版本时,启动失败,dmesg 显示以下错误: [ +0.001258] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x117d0 [ +0.000021] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x117d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.008868] remoteproc remoteproc0: Boot failed: -22 克劳德告诉我这是.bss .heap .stack的问题。部分,因为 PhysAddr 为 `0x0fff37a0`,大小现在为 `0x117d0`。`0x0fff37a0 + 0x117d0 = 0x10004f70` 超出了 M33 代码 TCM 地址范围0x0ffe0000 .. 0x10000000 。解释令人困惑,但我的理解是静态初始化必须放在“代码”部分,导致它溢出,即使“系统”TCM 范围内有足够的空间(另外 128 kB)。所以,这或许说得通。 动态(堆)分配: 例如。: uint32_t *p_sample_queue = malloc(SAMPLE_QUEUE_LENGTH, sizeof(uint32_t)); C 语言默认可用的堆大小只有 1 kB,因此malloc无法处理我们的大缓冲区。 我修改了项目的 CMake 文件,通过__heap_size__分配了更大的堆内存 (32 kB),该参数会传递给链接器脚本: mcux_add_linker_symbol( SYMBOLS "__stack_size__=0x400 \ __heap_size__=0x8000 \ <---- Added __use_shmem__=1 \ __multicore__=1 \ " ) 版本输出和 ELF 文件信息: Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 103760 B 108 KB 93.82% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. #### ELF file info: #### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x193d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack 这似乎让问题变得更糟,而不是更好(.bss/.heap/.stack)。位于 PhysAddr 0x0fff37a0,大小 0x193d0)。 [ +0.001320] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x193d0 [ +0.000019] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x193d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.002908] remoteproc remoteproc0: Boot failed: -22 我原以为使用堆分配可以缩小代码段的大小,并从数据段分配内存。上面版本输出中显示的“m_data”部分确实更大。 我不太理解“PhysAddr”,它与参考手册中的“Code TCM”范围相匹配,即使对于应该在“System TCM”区域内的内容也是如此(我认为?)。“VirtAddr”下的地址似乎是正确的。 为什么 ELF 文件仍然尝试放置 .bss/.heap/.stack 文件?PhysAddr 0x0fff37a0 处的数据为什么在使用运行时堆分配时如此之大?有没有办法在“系统 TCM”区域中分配我的大缓冲区? Re: i.MX93 M33 Can't Use System TCM RAM for Allocation 嗨@jcolebaker 您可以选择将数据/bss/堆/堆栈的 LMA 更改为系统 TCM。在 MCUX 链接器脚本中,将数据段的加载地址 (AT) 从代码 TCM 更改为系统 TCM,以便 PhysAddr 也位于 0x2000_0000: .data : { ... } > m_data AT> m_data /* Do not use AT> m_text */ .bss : { ... } > m_data 当 LMA == VMA 且两者都在系统 TCM 中时,PhysAddr 变为 0x2000_xxxx,这与 remoteproc 驱动程序中 {0x20000000, …, 0x00040000} (256 KB) 范围内的条目匹配,从而使 remoteproc 能够正确转换。 此致, 志明
View full article
s32k144 MBDツールボックスを使用したI2Cの読み書き こんにちは、 私はs32k144を使用して、外部EEPROMからのデータ読み書きを行っています。モデルを下に添付します。データの書き込みはできますが、読み込み時に255+NACKが出力されます。何か見落としているのでしょうか? Sriram_0-1737789999186.pngSriram_0-1737789999186.png Sriram_1-1737790013461.pngSriram_1-1737790013461.png I2CmasterブロックでEEPROMのレジスタアドレスを指定する方法はありますか? Sriram_2-1737790096449.pngSriram_2-1737790096449.png この問題について皆さん助けてもらえますか? ありがとう Re: I2C read and write using s32k144 MBD toolbox こんにちは、 私も、マスターとしてS32K144 、スレーブとしてST M24C04 EEPROMを使用したI2C通信で同じ問題に直面しています。 同じマイクロコントローラとEEPROMを使っているので、解決策が見つかっているか確認したいです。もしこの問題が解決したなら、その解決策を教えていただけるか、どう解決したのか教えていただけませんか? ご協力ありがとうございます。 Re: I2C read and write using s32k144 MBD toolbox 私はM24C02-DRE EEPROMを使用しています
View full article
i.MX93 M33 System TCM RAMを割り当てに使用できません 当社はIoTデバイス向けにi.MX9352を評価しています。私はM33コア用のアプリケーションを作成しました。これにはペリフェラルから大量のサンプルを収集する時間的責任のIO操作が含まれます。開発のために、Linuxからリモートプロックを使ってM33コードを読み込み、起動しています。コードはC言語で書かれ、MPUXpresso 26.06.00 SDKを使用しています。 コードはうまく動作するようになったのですが、今度はサンプル用の大きなバッファ(約24kB)が必要です。私はこれを静的配列として、または`malloc`で割り当てられたヒープとして追加しようと試みました。いずれにせよ、コンパイル出力では十分なRAMがあると示されているのに、私はすぐにRAMが切れてしまうようです。 作業版: こちらは小さなバッファのビルドのメモリ情報で、**問題なく動作します*(ただしバッファは私たちの要件には小さすぎます)。 Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78300 B 129928 B 60.26% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 48016 B 108 KB 43.42% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. ELFファイルからの情報は以下のとおりです。 readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131dc 0x131dc RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3654 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37e0 0x00000 0x0ba10 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack 大規模な静的割り当て: こちらは**24 kBの静的割り当てバッファ**を持つビルドのメモリとELFファイル情報です。 つまり: static uint32_t m_sample_queue[SAMPLE_QUEUE_LENGTH]; // SAMPLE_QUEUE_LENGTH = 6000 Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 72016 B 108 KB 65.12% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. ### (As expected, the `m_data` section has increased in size.) ### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x117d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack Linuxでremoteprocを使ってこのバージョンを起動しようとすると起動できず、dmesgは以下のエラーを表示します。 [ +0.001258] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x117d0 [ +0.000021] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x117d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.008868] remoteproc remoteproc0: Boot failed: -22 クロードは、これは.bss .heap .stackの問題だと私に言った。PhysAddr が `0x0fff37a0` で、サイズが `0x117d0` になったため、このセクションが使用不可となります。`0x0fff37a0 + 0x117d0 = 0x10004f70` は、M33 コード TCM アドレス範囲0x0ffe0000 .. 0x10000000を超えています。説明は分かりにくかったのですが、私の解釈では、静的初期化は「code」セクションに記述する必要があり、「system」TCM領域(残りの128kB)には十分な空き容量があるにもかかわらず、オーバーフローが発生してしまうということです。だから、これで納得できるかもしれません。 動的(ヒープ)割り当て: 例えば。: uint32_t *p_sample_queue = malloc(SAMPLE_QUEUE_LENGTH, sizeof(uint32_t)); Cで利用可能なデフォルトのヒープサイズはわずか1 kBなので、 malloc は大きなバッファでは失敗します。 プロジェクトのCMakeを修正し、 __heap_size__を介してより大きなヒープ(32kB)を割り当てるようにしました。この__heap_size__はリンカースクリプトに渡されます。 mcux_add_linker_symbol( SYMBOLS "__stack_size__=0x400 \ __heap_size__=0x8000 \ <---- Added __use_shmem__=1 \ __multicore__=1 \ " ) ビルド出力とELFファイル情報: Memory region Used Size Region Size %age Used m_interrupts: 1140 B 1144 B 99.65% m_text: 78240 B 129928 B 60.22% m_m33_suspend_ram: 0 B 8 KB 0.00% m_a55_suspend_ram: 0 B 4 KB 0.00% m_data: 103760 B 108 KB 93.82% m_rsc_tbl: 0 B 4 KB 0.00% build finished successfully. #### ELF file info: #### readelf -l imx_m33.elf Elf file type is EXEC (Executable file) Entry point 0xffe0595 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x0ffe0000 0x0ffe0000 0x00474 0x00474 R 0x1000 LOAD 0x001478 0x0ffe0478 0x0ffe0478 0x131a0 0x131a0 RWE 0x1000 LOAD 0x015000 0x20003000 0x0fff3618 0x00170 0x00170 RW 0x1000 LOAD 0x000180 0x20003180 0x0fff37a0 0x00000 0x193d0 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .interrupts 01 .resource_table .text .ARM .init_array .fini_array 02 .data 03 .bss .heap .stack これは問題を改善するどころか悪化させているようだ(.bss/.heap/.stackPhysAddr 0x0fff37a0、サイズ 0x193d0)。 [ +0.001320] imx-rproc remoteproc-cm33: Translation failed: da = 0xfff37a0 len = 0x193d0 [ +0.000019] remoteproc remoteproc0: bad phdr da 0xfff37a0 mem 0x193d0 [ +0.000006] remoteproc remoteproc0: Failed to load program segments: -22 [ +0.002908] remoteproc remoteproc0: Boot failed: -22 ヒープ割り当てを使うことでコードセクションを小さくし、データセクションからメモリを割り当てられると思っていました。上記のビルド出力に示されている「m_data」セクションは確かに大きいです。 リファレンスマニュアルの「Code TCM」の範囲に一致する「PhysAddr」の意味がよく分かりません。本来「System TCM」領域にあるべきもの(だと思うのですが)についてもです。「VirtAddr」の下のアドレスは正しいようです。 ELF ファイルはなぜまだ .bss/.heap/.stack を配置しようとするのかPhysAddr 0x0fff37a0のデータについて、なぜランタイムヒープ割り当てを使うとこんなに大きいのでしょうか?また、「System TCM」領域に大きなバッファを割り当てる方法はありますか? Re: i.MX93 M33 Can't Use System TCM RAM for Allocation こんにちは、 @jcolebakerさん データ/BSS/ヒープ/スタックのLMAをSystem TCMに変更することもできます。MCUXリンカースクリプトでは、データセグメントのロードアドレス(AT)をコードTCMからSystem TCMに変更し、PhysAddrも0x2000_0000に当てはまるようにします。 .data : { ... } > m_data AT> m_data /* Do not use AT> m_text */ .bss : { ... } > m_data LMA == VMAが両方ともSystem TCMにある場合、PhysAddrは0x2000_xxxxとなり、remoteprocドライバーの{0x20000000, ..., 0x00040000}(256 KB)の範囲に一致し、remoteprocが正しく翻訳できるようにします。 よろしくお願いします、 志明
View full article
P3H2840 debugging issues consultation Currently, I'm debugging based on the official P3H2840 demo and found that the temperature sensor readings on the demo differ between I2C and I3C modes (as shown in the image below). Is this normal? Re: p3h2840调试问题咨询 Hi, The 0xff second byte you are seeing on every I3C mode register read is not correct and points to a hub configuration issue. For reference, the on-board temperature sensors on the P3H2x4xHN-ARD are NXP P3T1755DP devices, which are fully I3C-capable, so the readings should be identical in both modes once the hub is correctly set up. Please check the following three items: Dynamic address assignment — The P3T1755DP powers up in I2C mode and must receive a dynamic address (via ENTDAA, SETAASA, or SETDASA) before I3C private transfers will work. If i3c_xfer is called before this step completes, the device cannot respond correctly to I3C frames, and the second byte will read as 0xff . Confirm that the address assignment CCC ran successfully and that 0x4c is the assigned dynamic address. Burst Length enable — REG#17[6] (BL_ENABLE) — If this bit is set, the I3C write phase must include a Burst Length byte after the register pointer. If your i3c_xfer call sends only 1 write byte (register address), the hub receives an incomplete frame and the read response is misaligned, causing 0xff on the second byte. Please read back REG#17 and confirm whether bit 6 is set. If it is, either add the BL byte to your write payload or clear BL_ENABLE if it is not needed. Target port VCCIO — REG#22 — In I3C mode the target port uses push-pull drive levels referenced to the VCCIO setting in REG#22. If this does not match the actual P3T1755DP supply voltage, data bytes transferred in push-pull mode can be corrupted. Please confirm that REG#22 reflects the correct operating voltage for the target port the sensor is connected to.
View full article
MPC5744P EVM – CAN1/CAN2 Support with External CAN Transceiver Hello Dear, I would like to clarify whether the MPC5744P EVM supports operation of two CAN channels using external CAN transceivers. I have successfully tested CAN0 on the EVM using the onboard/inbuilt CAN transceiver, and the CAN0 communication is working as expected. Now, I have configured CAN1 and CAN2 with the appropriate pin mapping to interface with external CAN transceivers. Could you please confirm whether CAN1 and CAN2 can be configured and operated successfully with external CAN transceivers on the MPC5744P EVM? If yes, could you please provide any recommended configuration, hardware connections, or specific settings that need to be considered for CAN1/CAN2 operation? Your guidance and support would be greatly appreciated. Thanks in advance for your help. Re: MPC5744P EVM – CAN1/CAN2 Support with External CAN Transceiver Hi, Yes, CAN1 and CAN2 can be used with external CAN transceivers on MPC5744P-based evaluation boards. The MPC5744P device provides three independent FlexCAN modules (CAN0, CAN1, and CAN2), and CAN1/CAN2 can be routed to external transceivers through their corresponding MCU TX/RX pins, if no onboard transceiver is available and connected. The device supports operation of all FlexCAN instances independently.  For CAN1/CAN2, please ensure: The selected FlexCAN instance is configured correctly in software. The corresponding TX and RX pins are configured for the FlexCAN alternative function. The external CAN transceiver is powered and connected correctly. Proper CAN bus termination is present. Board-specific jumper settings or routing options may depend on the exact EVM revision. If you can provide the EVM part number or revision, we can check whether any additional hardware configuration is required. BR, Petr
View full article