micro-ROS / micro_ros_setup

Support macros for building micro-ROS-based firmware.
Apache License 2.0
365 stars 133 forks source link

Generate Static Library for TM4C123 Series #285

Closed altineller closed 2 years ago

altineller commented 3 years ago

I started by writing the serial_transport_external.c:

#define SYSTICKHZ  1000UL

#include <stdbool.h>
#include <stdint.h>

#include <inc/hw_types.h>
#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>
#include <driverlib/sysctl.h>
#include <driverlib/gpio.h>
#include <driverlib/rom.h>
#include <driverlib/rom_map.h>
#include <driverlib/systick.h>
#include <driverlib/pin_map.h>
#include <driverlib/usb.h>
#include <usblib/usblib.h>
#include <usblib/usbcdc.h>
#include <usblib/usb-ids.h>
#include <usblib/device/usbdevice.h>
#include <usblib/device/usbdcdc.h>

#include "usb_serial_structs.h"

#include <uxr/client/profile/transport/serial/serial_transport_external.h>
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>

uint32_t ui32SysClkFreq;
volatile uint32_t g_ui32milliseconds;

bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, int fd, uint8_t remote_addr, uint8_t local_addr) {

      ui32SysClkFreq = MAP_SysCtlClockGet();
      g_ui32milliseconds = 0;

      // setup timer
      SysTickIntRegister(SystickIntHandler);
      MAP_SysTickPeriodSet(ui32SysClkFreq/SYSTICKHZ);
      MAP_SysTickEnable();
      MAP_SysTickIntEnable();

      // enable usb
      MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

      // usb pins
      MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
      MAP_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_5 | GPIO_PIN_4);

      // tx and receive buffers
      USBBufferInit(&g_sTxBuffer);
      USBBufferInit(&g_sRxBuffer);

      // usb stack mode = device mode + vbus monitoring
      USBStackModeSet(0, eUSBModeForceDevice, 0);

      // init device on bus
      USBDCDCInit(0, &g_sCDCDevice);

      // usb int handler
      USBIntRegister(USB0_BASE, USB0DeviceIntHandler);

      MAP_IntMasterEnable();
}

bool uxr_close_serial_platform(struct uxrSerialPlatform* platform) {
      return true;
}

size_t uxr_write_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, uint8_t* errcode) {

    uint32_t written_bytes = USBBufferWrite(&g_sTxBuffer, buf, len);
    if(written_bytes != len) {
        *errcode = 1;
    }
    return written_bytes;

}

size_t uxr_read_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode) {

    uint32_t read_bytes = USBBufferRead(&g_sRxBuffer, buf, len);
    if(read_bytes != len) {
        *errcode = 1;
    }
    return read_bytes;

}

static void SystickIntHandler() {
    ++g_ui32milliseconds;
}

uint32_t getSysClkFreq(void) {
    ui32SysClkFreq;
}

uint32_t time() {
   return g_ui32milliseconds;
}

As for the cmake file, I think a good starting point is: https://github.com/vmatos/tiva-c-projects/blob/master/examples_tm4c123/blinky_cmake_cpp/tm4c123g.cmake

AND:

https://github.com/micro-ROS/micro_ros_arduino/blob/foxy/extras/library_generation/teensy32_toolchain.cmake

I have some questions: In the cmake file, what are the necessary flags to facilitate microros?

Which parts from the first cmake file I should migrate to the second file.

The first link that contains the cmake file has some extra flags for c, cxx, and asm. I believe asm is not required for this case.

I have deleted flags one by one, that was in the microros teensy32_toolchain.cmake file, and the difference is:

set(FPU "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp")

set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -mthumb ${CPU}  ${FPU} -MD")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb ${CPU} ${FPU} -std=gnu99 -Os -MD -Wall -pedantic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb ${CPU} ${FPU}  -Os -MD -Wall -pedantic")

Do we need those flags? -Wall, -pedantic, -MD, -OS and -std=gnu99

Also, I need to include a $TIVA_WARE_PATH and also link to a lib.

Any ideas/recommendations/help greatly appreciated.

pablogs9 commented 3 years ago

Hello, writing transport for micro-ROS approach have changed slightly, now you need to write the same functions but they will be set as callbacks at run time: check this.

Regarding the flags of the CMake toolchain, the only ones related to micro-ROS are: -D'RCUTILS_LOG_MIN_SEVERITY=RCUTILS_LOG_MIN_SEVERITY_NONE, -DCLOCK_MONOTONIC=0 and -D'__attribute__(x)=' (if your compiler has issues with GCC attributes).

The others are completely dependant on how are you going to link the micro-ROS library against your app. Finally, I guess that ASM flags are not required here.

altineller commented 3 years ago

Hello,

Setting callbacks at run time like in micro_ros_arduino/src/micro_ros_arduino.h and micro_ros_arduino/src/default_transports.cpp ?

Could I clone the micro_ros_arduino, and use it as a starting point? Do you think this is a good approach?

Best Regards, C.

pablogs9 commented 3 years ago

Yes, I think that using the Arduino library as a way of generating your static libs and transports is a good entry point.

You have the micro-ROS API for setting the transports here: https://github.com/micro-ROS/micro_ros_arduino/blob/fa5f82db4022483924644977c540418284fa6c66/src/micro_ros_arduino.h#L25