Teste semf
Kontakt

Setting up a project

General

A DataStream is a binary stream of encoded information which is 100% independent of the host computers’ operating system, CPU or byte order. For example, a DataStream that is written by a e.g. From scratch on, we focused on using time as efficient as possible. That’s why we simplified the “creating a new project” process as possible.

In the following steps we create a very simple project using semf library.We assume you already set up a microcontroller project and uses a Eclipse based IDE. We set this up for an STM32F4 microcontroller and used STM32CUBEMX / STM32CUBEIDE for hardware initialization.

C++ Project

Convert your project to a C++ project by a right mouse click -> Convert to C++.Copy the semf library into a new created semf folder in the root directory of your project

Library Linkage

Link the semf library to you project by adding the library and include path and the library itself. You can find these settings in Project -> Settings -> C/C++ General -> Paths and Symbols. Make sure you add both to the C++ language and all configurations:

  1. Go to Inclues and add the semf library path.
  2. Go to Library Paths and add the semf library path.
  3. Go to Libraries and add the name of the semf library file with a “:” in front of the name (e.g. :semf_cortex-m4_fpv4-sp-d16.a).

STM32 Systick

Setting up a new project with STM32CUBEMX / STM32CUBEIDE the systick callback is never called.

We add this callback in the stm32f4xx_it.c file.

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  HAL_SYSTICK_Callback();  // this line has to be added
  /* USER CODE END SysTick_IRQn 1 */

C to Cpp Bridge

maincpp.h

Create the following maincpp.h file in the same directory as the main.h.

#ifndef CPPMAIN_H_
#define CPPMAIN_H_

void cppInit(); // Board support package and application initialization.
void cppMainLoop(); // Application loop.

#endif /* CPPMAIN_H_ */

maincpp.cpp

Create the following maincpp.cpp file in the same directory as the main.c.

#include "bsp.h"
#include "app.h"  // include your application

extern "C" {
/** Cpp init */
void cppInit()
{
	Bsp::instance().init();
	App::instance().init();
}

/** Main-loop for cpp code */
void cppMainLoop()
{
	App::instance().mainLoop();
}

}

main.c Changes

Add following code in the main.c to enter the cpp part of the project.

// ...
#include "maincpp.h"
// ...
// ...
int main(void)
{
	// ...
	cppInit();
	while (1)
	{
		cppMainLoop();
		// ...
	}
}

Board Support Package

semf makes applications hardware independent. Somewhere in the project we need to define all the hardware dependent stuff. To do that, let’s create a Bsp class.

In the following example we make the Systick, one gpio and an analog to digital converter (adc) accessable from the application.

bsp.h

Create the following bsp.h file in the same directory as the main.h.

#ifndef BSP_H_
#define BSP_H_

#include "HardwareAbstraction/Stm32F4/stm32f4gpio.h"  // For using gpios
#include "HardwareAbstraction/Stm32F4/stm32f4systick.h" // For using systick
#include "HardwareAbstraction/Stm32F4/stm32f4analogin.h" // For using adc
#include "main.h" // For having the hardware handlers available
#include "stm32f4xx_hal.h"  // For having access to the microcontroller hardware

class Bsp
{
public:
	static Bsp& instance();  // Returns the pointer to the bsp

	struct Gpios
	{
		semf::Stm32F4Gpio gpio1;
	};
	Gpios& gpios();  // Returns the reference to all added gpios
	struct Timers
	{
		semf::Stm32F4Systick& systick;
	};
	Timers& timers();  // Returns reference to all added timers
	struct Adcs
	{
		semf::Stm32F4AnalogIn adc1;
	};
	Adcs& adcs();  // Returns the reference to all added adcs
	// ...

	void init();  // Does the initialization
private:
	Bsp();
	Gpios m_gpios;
	Timers m_timers;
	Adcs m_adcs;

	// ...
};

#endif /* BSP_H_ */

bsp.cpp

Create the following bsp.cpp file in the same directory as the main.c.

#include "bsp.h"

extern ADC_HandleTypeDef hadc1;

Bsp& Bsp::instance()
{
	static Bsp instance;
	return instance;
}

Bsp::Gpios& Bsp::gpios()
{
	return m_gpios;
}

Bsp::Timers& Bsp::timers()
{
	return m_timers;
}

Bsp::Adcs& Bsp::adcs()
{
	return m_adcs;
}

void Bsp::init()
{
	// Do something ...
}

Bsp::Bsp() 
	:m_gpios
	 {
		semf::Stm32F4Gpio(B1_GPIO_Port, B1_Pin) 
	 }, 
	 m_timers
	 { 
		semf::Stm32F4Systick::instance()
	 }, 
	 m_adcs
	 { 
		semf::Stm32F4AnalogIn(hadc1)
	 } 
{ 

}

Application

Now we can set up our micro application.

app.h

Create the following app.h file in the same directory as the main.h.

#ifndef APP_H_
#define APP_H_

#include "bsp.h"
#include "System/timebase.h" 
#include "System/softwaretimer.h" 
#include "Output/digitalout.h"

class App
{
public:
	static App& instance();
	void init();
	void mainLoop();
	
private:
	App();

	semf::TimeBase m_systickBase; 
	semf::SoftwareTimer m_swTimer; 
	semf::DigitalOut m_dOut;
};

#endif /* APP_H_ */

app.cpp

Create the following app.cpp file in the same directory as the main.c.

#include "app.h"

App& App::instance()
{
	static App instance;
	return instance;
}

void App::init()
{
	// Setting up an digial out toggeling with the swTimer's timeout 
	swTimer.timeout.connect(&m_dOut, &semf::DigitalOut::toggle);
}

void App::mainLoop()
{
	// do something
}

App::App() 
	:m_systickBase(Bsp::instance().timers().systick, true),
	 m_swTimer(m_systickBase, 5000, true),
	 m_dOut(Bsp::instance().gpios().gpio1)
{ 

}

zurück zur Dokumentation