Skip to content

Cryptoauthlib, STM32, arm-none-eabi-gcc, libopenCM3 and makefiles. #211

Description

@krish2487

Hello folks,

I am trying to use cryptoauthlib with an STM32 controller and libopenCM3 HAL.
I have run into a roadblock while trying to integrate the library into my application.
I have started with the libopenCM3 template from here
and I have renamed the "my-common-code" to "shared_libs" and "my-project" to "cryptoauth_test". I have then cloned the cryptoauthlib into the "shared_libs" folder and created the "build" folder under the "cryptoauthlib" folder.

So my folder structure looks like this.

.
├── cryptoauth_test
│   └── bin
├── libopencm3
.....
│   ├── include
│   │   ├── libopencm3
│   │   │   ├── cm3
│   │   │   ├── dispatch
│   │   │   ├── efm32
│   │   │   ├── ethernet
│   │   │   ├── lm3s
│   │   │   ├── lm4f
│   │   │   ├── lpc13xx
│   │   │   ├── lpc17xx
│   │   │   ├── lpc43xx
│   │   │   ├── msp432
│   │   │   ├── sam
│   │   │   ├── stm32
│   │   │   ├── usb
│   │   │   └── vf6xx
│   │   └── libopencmsis
│   │       ├── dispatch
│   │       ├── efm32
│   │       ├── lm3s
│   │       ├── lpc13xx
│   │       ├── lpc17xx
│   │       ├── lpc43xx
│   │       ├── msp432
│   │       ├── sam
│   │       ├── stm32
│   │       └── vf6xx
└── shared_libs
    ├── cryptoauthlib
    │   ├── app
    │   │   ├── api_206a
    │   │   ├── ip_protection
    │   │   ├── pkcs11
    │   │   ├── secure_boot
    │   │   └── tng
    │   ├── build
    │   │   ├── CMakeFiles
    │   │   └── lib
    │   ├── harmony
    │   │   ├── config
    │   │   ├── src
    │   │   └── templates
    │   ├── lib
    │   │   ├── atcacert
    │   │   ├── calib
    │   │   ├── crypto
    │   │   ├── hal
    │   │   ├── host
    │   │   ├── jwt
    │   │   ├── mbedtls
    │   │   ├── openssl
    │   │   ├── pkcs11
    │   │   └── wolfssl
    │   ├── python
    │   │   ├── cryptoauthlib
    │   │   └── tests
    │   ├── test
    │   │   ├── api_atcab
    │   │   ├── api_calib
    │   │   ├── atcacert
    │   │   ├── jwt
    │   │   ├── tng
    │   │   └── vectors
    │   └── third_party
    │       ├── hal
    │       ├── hidapi
    │       └── unity


I navigated to the cryptoauthlib folder and created my custom hal inside the "lib/hal" folder called hal_i2c_stm3.c
The contents are like this

#include <stdio.h>
#include <string.h>
#include "../atca_iface.h"
#include "../cryptoauthlib.h"
#include "atca_hal.h"
#include "delay.h"
#include "libopencm3/stm32/rcc.h"
#include "libopencm3/stm32/gpio.h"
#include "libopencm3/stm32/i2c.h"

#ifdef ATCA_HAL_STM32

void atca_delay_ms(uint32_t ms) { delay_ms(ms); }

void hal_i2c_change_baud(ATCAIface iface, uint32_t speed)
{
	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg)
{
	rcc_clock_setup_in_hse_8mhz_out_72mhz();// For "blue pill"
	rcc_periph_clock_enable(RCC_GPIOB);  // I2C
	rcc_periph_clock_enable(RCC_AFIO);
	rcc_periph_clock_enable(RCC_I2C1);
	gpio_set_mode(GPIOB,
	              GPIO_MODE_OUTPUT_50_MHZ,
	              GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
	              GPIO8 | GPIO9);
	gpio_set(GPIOB, GPIO8 | GPIO9);

	gpio_primary_remap(0, 0);
}

ATCA_STATUS hal_i2c_post_init(ATCAIface iface) { return ATCA_SUCCESS; }

ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
	ATCAIfaceCfg *cfg = iface->mIfaceCFG;
	txdata[0] = 0x03;
	txlength++;

	i2c_send_start(I2C1);
	for (uint8_t i = 0; i < txlength; i++)
		{
			i2c_send_data(I2C1, txdata);
			txdata++;
		}
	i2c_send_stop(I2C1);

	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata,
                            uint16_t *rxlength)
{
	ATCAIfaceCfg *cfg = iface->mIfaceCFG;
	int addr = cfg->atcai2c.slave_address;

	rxdata[0] = i2c_get_data(I2C1);
	// rxdata[0] = Wire.read();
	*rxlength = rxdata[0];

	if (*rxlength > 1)
		{
			for (uint8_t i = 0; i < *rxlength - 1; i++)
				{
					rxdata = i2c_get_data(I2C1);
				}

		}

	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_release(void *hal_data)
{
	i2c_send_stop(I2C1);
	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int addr = cfg->atcai2c.slave_address;
	uint8_t sleep_data = 0x01;

	i2c_send_start(I2C1);
	i2c_send_data(I2C1, sleep_data);
	i2c_send_stop(I2C1);

	return ATCA_SUCCESS;
}

ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses)
{
	return ATCA_UNIMPLEMENTED;
}

ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg *cfg,
                                     int *found)
{
	return ATCA_UNIMPLEMENTED;
}

#endif

I then navigated to the build folder and and according to the instructions here

ran then configuration and build by issuing the following commands.

 cmake -DATCA_ATECC608A_SUPPORT=ON -DATCA_HAL_I2C=ON -DATCA_BUILD_SHARED_LIBS=OFF ../  
 cmake --build .    

I ended up with the "libcryptoauthlib.a" and "atca_config.h" file inside the "lib" folder under the "build" folder.
I copied the "atca_config.h" file into my actual project source directory "cryptoauth_test".

I have then modified the makefile inside the project source to link the cryptoauthlib.a library and added the necessary paths. My makefile looks like this now

PROJECT = crypto_test
BUILD_DIR = bin

SHARED_DIR = ../shared_libs ../shared_libs/cryptoauthlib/lib
CFILES = main.c
CFILES += delay.c
TGT_CFLAGS += -DATCA_HAL_STM32
TGT_LDFLAGS += -L ../shared_libs/cryptoauthlib/build/lib/ -lcryptoauth

# TODO - you will need to edit these two lines!
DEVICE=stm32f103rct6
# ST-FLASH = st-flash
OOCD_INTERFACE = jlink
OOCD_TARGET = stm32f1x
# OOCD_FILE = board/stm32ldiscovery.cfg

# You shouldn't have to edit anything below here.
VPATH += $(SHARED_DIR)
INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR))
OPENCM3_DIR=../libopencm3

include $(OPENCM3_DIR)/mk/genlink-config.mk
include ../rules.mk
include $(OPENCM3_DIR)/mk/genlink-rules.mk

size: all
	$(SIZE) $(PROJECT).elf

write: $(PROJECT).bin
	$(ST-FLASH) write $(PROJECT).bin 0x8000000

erase:
	$(ST-FLASH) erase

Notice the ATCA_HAL_STM32 flag that is also defined in the custom HAL.

I have then created a sample main.c file to initialize the ATECC608A chip. This is what my main file looks like

#include <stdlib.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
#include "libopencm3/cm3/nvic.h"
#include "libopencm3/cm3/systick.h"
#include "libopencm3/stm32/spi.h"
#include "usb.h"
#include "atca_config.h"
#include "cryptoauthlib.h"
#include "delay.h"

uint32_t temp;
char test_string[13] = "Hello World\n";
uint32_t i = 2000000;

int main(void)
{

	rcc_clock_setup_in_hsi_out_48mhz();

	//Enable GPIOC Peripheral clock
	rcc_periph_clock_enable(RCC_GPIOB);
	//Output mode, no pull ups or pull down
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0 | GPIO1);
	//Set GPIO8 and clear GPIO9 to see toggle
	gpio_set(GPIOB, GPIO0);
	gpio_clear(GPIOB, GPIO1);

	usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
	usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
	nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);

	temp = 0;

	//Sets systick clocksource to clock / 8 = 6000000 counts per second
	systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
	//Sets systick reload counter to give a 'tick' once a millisecond.
	// 48000000 / 48000 = 1000 overflows every second or 48000-1
	systick_set_reload(5999);
	//Enables systick interrupt - defined in sys_tick_interrupt() handler
	systick_interrupt_enable();
	//Starts the systick counter.
	systick_counter_enable();
	// usbd_ep_write_packet(usbd_dev, 0x82, "Hello World\n", strlen("Hello World\n"));
	setup_delay_timer();

	delay_ms(10000);
	usbd_ep_write_packet(usbd_dev, 0x82, "Hello World\n", strlen("Hello World\n"));
	delay_ms(10000);

	ATCAIfaceCfg cfg = cfg_ateccx08a_i2c_default;

	ATCA_STATUS ret = atcab_init(&cfg_ateccx08a_i2c_default);

	// Get random number
	uint8_t rand[32];
	ret = atcab_random(rand);

	if (ret != ATCA_SUCCESS)
		{
			USB_Write_Message("Error Initializing Cryptochip", strlen("Error Initializing Cryptochip"));
		}

	delay_ms(10000);

	while (1)
		{

		}

}


void sys_tick_handler(void)
{
	temp++;
	if (temp >= 1000)
		{
			gpio_toggle(GPIOB, GPIO1);
			temp = 0;
		}
}

// This is the interrupt handler for low priority USB events. Implementing a
// function with this name makes it the function used for the interrupt.
// TODO: Handle the other USB interrupts.
void usb_lp_can_rx0_isr(void)
{

	gpio_toggle(GPIOB, GPIO0);
	usbd_poll(usbd_dev);

}


I have included both the cryptoauthlib.h and atca_config.h file, and I do hope I have added the necessary paths for the makefile to pickup the sources.
However, this is where I am running into issues.
When i run make in my project source folder I get an "undefined reference to..." error..
This is what the console output looks like in a verbose manner.

make V=1
  CC    main.c
arm-none-eabi-gcc -DATCA_HAL_STM32  -std=c11 -ggdb3 -mcpu=cortex-m3 -mthumb -msoft-float -fno-common  -ffunction-sections -fdata-sections -fstack-usage -Wextra -Wshadow -Wno-unused-variable -Wimplicit-function-declaration -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes  -MD -Wall -Wundef -I. -I../shared_libs -I../shared_libs/cryptoauthlib/lib -I. -I../libopencm3/include -I. -I../shared_libs -I../shared_libs/cryptoauthlib/lib -I. -I../libopencm3/include  -DSTM32F1 -DSTM32F103RCT6 -I../libopencm3/include -o bin/main.o -c main.c
In file included from main.c:9:
usb.h:210:13: warning: 'cdcacm_data_tx_cb' defined but not used [-Wunused-function]
  210 | static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep)
      |             ^~~~~~~~~~~~~~~~~
  CC    ../shared_libs/delay.c
arm-none-eabi-gcc -DATCA_HAL_STM32  -std=c11 -ggdb3 -mcpu=cortex-m3 -mthumb -msoft-float -fno-common  -ffunction-sections -fdata-sections -fstack-usage -Wextra -Wshadow -Wno-unused-variable -Wimplicit-function-declaration -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes  -MD -Wall -Wundef -I. -I../shared_libs -I../shared_libs/cryptoauthlib/lib -I. -I../libopencm3/include -I. -I../shared_libs -I../shared_libs/cryptoauthlib/lib -I. -I../libopencm3/include  -DSTM32F1 -DSTM32F103RCT6 -I../libopencm3/include -o bin/delay.o -c ../shared_libs/delay.c
  GENLNK  stm32f103rct6
arm-none-eabi-gcc -E -mcpu=cortex-m3 -mthumb -msoft-float -DSTM32F1 -DSTM32F103RCT6 -D_ROM=256K -D_RAM=48K -D_ROM_OFF=0x08000000 -D_RAM_OFF=0x20000000 -P -E ../libopencm3/ld/linker.ld.S > generated.stm32f103rct6.ld
  LD    crypto_test.elf
arm-none-eabi-gcc -L ../shared_libs/cryptoauthlib/build/lib/ -lcryptoauth -Tgenerated.stm32f103rct6.ld -L../libopencm3/lib -nostartfiles -mcpu=cortex-m3 -mthumb -msoft-float -specs=nano.specs  -Wl,--build-id=uuid -Wl,-Map=crypto_test.map -L../libopencm3/lib bin/main.o bin/delay.o -lopencm3_stm32f1 -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group -o crypto_test.elf
/Users/srikrishnachaitanyanarumanchi/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: bin/main.o: in function `main':
/Users/srikrishnachaitanyanarumanchi/Workspace/libopencm3/test/cryptoauth_test/main.c:55: undefined reference to `atcab_init'
/Users/srikrishnachaitanyanarumanchi/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: /Users/srikrishnachaitanyanarumanchi/Workspace/libopencm3/test/cryptoauth_test/main.c:59: undefined reference to `atcab_random'
/Users/srikrishnachaitanyanarumanchi/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: /Users/srikrishnachaitanyanarumanchi/Workspace/libopencm3/test/cryptoauth_test/main.c:68: undefined reference to `cfg_ateccx08a_i2c_default'
collect2: error: ld returned 1 exit status
make: *** [crypto_test.elf] Error 1

It looks like the compiler is linking the cryptoauthlib but is yet not finding the actual source for the functions it is complaining about as seen from this line here.

 LD    crypto_test.elf
arm-none-eabi-gcc -L ../shared_libs/cryptoauthlib/build/lib/ -lcryptoauth -Tgenerated.stm32f103rct6.ld -L../libopencm3/lib -nostartfiles -mcpu=cortex-m3 -mthumb -msoft-float -specs=nano.specs  -Wl,--build-id=uuid -Wl,-Map=crypto_test.map -L../libopencm3/lib bin/main.o bin/delay.o -lopencm3_stm32f1 -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group -o crypto_test.elf

I am not sure how to resolve this issue. I would be extremely grateful if someone more knowledgeable can point out what I am doing wrong and how I can fix this and get the library to link and successfully compile.

Or, if I am going about it the wrong way and there is in fact an easier way to integrate the library into a makefile project.. I am game for it as well.

Thanks in advance folks.
I apologize for the long post, but I feel like the more information I give about what and how I have done my work, will eable others to help me better. :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions