cancel
Showing results for 
Search instead for 
Did you mean: 

strncpy_s in STM32: undefined reference to `strncpy_s'

OIp.1
Associate III

Hi. I have the following code:

messageprocesser.h

#ifndef INC_MESSAGEPROCESSER_H_
#define INC_MESSAGEPROCESSER_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include "main.h"
#include "usbd_cdc.h"
#include <stdint.h>
#include <string.h>
#include <stdio.h>
 
void process_Message(uint8_t* message, uint16_t Len);
void message_Received(uint8_t* message, uint16_t Len);
void send_Message(uint8_t* cmd, uint8_t* data);
 
#endif /* INC_MESSAGEPROCESSER_H_ */

messageprocesser.c

/*
 * messageprocesser.c
 *
 *  Created on: Jan 30, 2023
 *     Sorry for the dead code. I left it there so the error messages would make sense.
 */
 
#include "messageprocesser.h"
#include "main.h"
#include "usbd_cdc_if.h"
#include <string.h>
 
//Sample cmd: TOARM_FIRMV_00000000_4C\r\n
#define MESSAGE_LENGTH 25
#define COMMAND_CHAR 6	//See SW Protocol or sample cmd
#define COMMAND_LENGTH 5
#define DATA_CHAR 12
#define DATA_LENGTH 8
#define CHECKSUM_CHAR 21
#define CHECKSUM_LENGTH 2
 
void process_Message(uint8_t* message, uint16_t Len){
	HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);
	unsigned char inputCmd[5];
	unsigned char inputMessage[8];
	unsigned char outputCmd[5];
	unsigned char outputData[8];
 
	//Function that separates message, inputCmd, and inputMessage.
 
//	strcpy((char*) inputCmd, (const char*)message + COMMAND_CHAR);
//	strcpy((char*) inputMessage, (const char*)message + DATA_CHAR);
	if (strncmp(inputCmd, "FIRMV", COMMAND_LENGTH) == 0){
		memcpy(outputCmd, "FIRMV", COMMAND_LENGTH);
		memcpy(outputData, "01050A00", DATA_LENGTH);
	}
	else{
		memcpy(outputCmd, "REEEE", COMMAND_LENGTH);
		memcpy(outputData, "99999999", DATA_LENGTH);
	}
 
//	message_Received(message, Len);
	send_Message(outputCmd, outputData);
}
 
void message_Received(uint8_t* message, uint16_t Len){
//	HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);
	//CDC_Transmit_FS(message, Len);
//	uint8_t inputCmd[5];
//	uint8_t inputMessage[8];
 
}
 
void send_Message(uint8_t* cmd, uint8_t* data){
	uint8_t outputMessage[MESSAGE_LENGTH] = "TOWST_";
	strncpy_s((char*) outputMessage + COMMAND_CHAR, COMMAND_LENGTH, (const char*) cmd, COMMAND_LENGTH);
	outputMessage[COMMAND_CHAR + COMMAND_LENGTH] = '_';
	strncpy((char*) outputMessage + DATA_CHAR, (const char*) data, DATA_LENGTH);	//Why does having 2 strcats break the system?
//	strncpy((char*) outputMessage + DATA_CHAR, (const char*) '_', 1);
	outputMessage[DATA_CHAR + DATA_LENGTH] = '_';
	strncpy((char*) outputMessage + CHECKSUM_CHAR, (const char*) "27", CHECKSUM_LENGTH);
	outputMessage[23] = '\r';
	outputMessage[24] = '\n';
//	strcat((char*) outputMessage, (const char*) data);
//	strcat((char*) outputMessage, (const char*) '_');
//	uint8_t test_message[64] = "TOWST_VERAK_01050A00_27\r\n";
//	CDC_Transmit_FS(test_message, sizeof(test_message));
	CDC_Transmit_FS(outputMessage, sizeof(outputMessage));
}

The error and the warning:

../Core/Src/messageprocesser.c: In function 'send_Message':
../Core/Src/messageprocesser.c:56:2: warning: implicit declaration of function 'strncpy_s'; did you mean 'strncpy'? [-Wimplicit-function-declaration]
   56 |  strncpy_s((char*) outputMessage + COMMAND_CHAR, COMMAND_LENGTH, (const char*) cmd, COMMAND_LENGTH);
      |  ^~~~~~~~~
      |  strncpy
c:\st\stm32cubeide_1.6.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_1.5.0.202011040924\tools\arm-none-eabi\bin\ld.exe: Core/Src/messageprocesser.o: in function `send_Message':
C:/Users/User/STM32CubeIDE/workspace_1.6.0/usbtest/Debug/../Core/Src/messageprocesser.c:56: undefined reference to `strncpy_s'

My understanding of strncpy_s is that it is a part of C11, and it is part of the string.h header file. I am unsure why my compiler does not consider strncpy_s as a valid preexisting operator.

My compiler is GNU11, so it should include C11 based on my understanding.

0693W00000YA3UPQA1.pngPlease let me know if more information is required.

1 ACCEPTED SOLUTION

Accepted Solutions

This function is defined in C11 Annex K, which is optional. Quoting from C11 (footnote 380 in Annex K):

Implementations that do not define _ _STDC_LIB_EXT1_ _ are not required to conform to these

specifications.

newlib does not appear to implement Annex K functions.

JW

View solution in original post

4 REPLIES 4

This function is defined in C11 Annex K, which is optional. Quoting from C11 (footnote 380 in Annex K):

Implementations that do not define _ _STDC_LIB_EXT1_ _ are not required to conform to these

specifications.

newlib does not appear to implement Annex K functions.

JW

Thank you. Is there a setting I could configure, or external file I could place within my project to implement Annex K?

Sorry, I don't use or even know any, and whatever I find using google you probably already know...

JW

Please see here and here