Страницы
▼
Страницы
▼
четверг, 10 августа 2017 г.
воскресенье, 6 августа 2017 г.
STM32F746 Memory Region
MPU_Region_InitTypeDef MPU_InitStruct_SDRAM;
MPU_Region_InitTypeDef MPU_InitStruct_FPGAKBD;
В 746-м, сразу после настройки FMC, возможен только доступ по четным (выровненным на 4 байта адресам). Для доступа к нечетным адресам надо еще настраивать MPU на эти области адресов. Иначе проц выпадает в Hard Fault exception handler.
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WT for SDRAM */
MPU_InitStruct_SDRAM.Number = MPU_REGION_NUMBER0;
MPU_InitStruct_SDRAM.BaseAddress = 0xD0000000;
MPU_InitStruct_SDRAM.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct_SDRAM.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_SDRAM.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_SDRAM.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_SDRAM.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_SDRAM.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_SDRAM.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_SDRAM.SubRegionDisable = 0x00;
MPU_InitStruct_SDRAM.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_SDRAM);
MPU_InitStruct_FPGAKBD.Number = MPU_REGION_NUMBER1;
MPU_InitStruct_FPGAKBD.BaseAddress = 0x60000000;
MPU_InitStruct_FPGAKBD.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct_FPGAKBD.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_FPGAKBD.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_FPGAKBD.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_FPGAKBD.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_FPGAKBD.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_FPGAKBD.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_FPGAKBD.SubRegionDisable = 0x00;
MPU_InitStruct_FPGAKBD.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_FPGAKBD);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
MPU_Region_InitTypeDef MPU_InitStruct_FPGAKBD;
В 746-м, сразу после настройки FMC, возможен только доступ по четным (выровненным на 4 байта адресам). Для доступа к нечетным адресам надо еще настраивать MPU на эти области адресов. Иначе проц выпадает в Hard Fault exception handler.
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WT for SDRAM */
MPU_InitStruct_SDRAM.Number = MPU_REGION_NUMBER0;
MPU_InitStruct_SDRAM.BaseAddress = 0xD0000000;
MPU_InitStruct_SDRAM.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct_SDRAM.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_SDRAM.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_SDRAM.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_SDRAM.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_SDRAM.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_SDRAM.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_SDRAM.SubRegionDisable = 0x00;
MPU_InitStruct_SDRAM.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_SDRAM);
MPU_InitStruct_FPGAKBD.Number = MPU_REGION_NUMBER1;
MPU_InitStruct_FPGAKBD.BaseAddress = 0x60000000;
MPU_InitStruct_FPGAKBD.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct_FPGAKBD.Enable = MPU_REGION_ENABLE;
MPU_InitStruct_FPGAKBD.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct_FPGAKBD.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct_FPGAKBD.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct_FPGAKBD.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct_FPGAKBD.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct_FPGAKBD.SubRegionDisable = 0x00;
MPU_InitStruct_FPGAKBD.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct_FPGAKBD);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
Fault Handler processing
#define USART_FLAG_TC ((uint16_t)0x0040)
static __INLINE void ITM_SendChar_My (uint32_t ch)
{
while( (USART1->ISR & USART_FLAG_TC ) == 0 )
{
;
}
USART1->TDR = (ch & (uint16_t)0x01FF);
}
void printErrorMsg(const char * errMsg)
{
while( *errMsg != 0 )
{
ITM_SendChar_My(*errMsg);
++errMsg;
}
}
static __INLINE void ITM_SendChar_My (uint32_t ch)
{
while( (USART1->ISR & USART_FLAG_TC ) == 0 )
{
;
}
USART1->TDR = (ch & (uint16_t)0x01FF);
}
void printErrorMsg(const char * errMsg)
{
while( *errMsg != 0 )
{
ITM_SendChar_My(*errMsg);
++errMsg;
}
}
Restarting UART DMA
Restarting UART DMA using HAL
HAL_DMA_Abort
HAL_UART_DMAStop
and recalling the DMA initialisation routine but it still doesn't restart correctly
add
__HAL_USART_CLEAR_OREFLAG(&huart1);
====================================================
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, 3000);
DMA_Cmd(DMA1_Channel1, ENABLE);
1. выключить канал dma
2. записать в CNDTR размер буфера
3. включить dma
при отладке с остановами работаеттолько такой код:
1a. выключить uart
1. выключить канал dma
2. записать в CNDTR размер буфера
2.a записать CCR то что писалось при инициализации
3. включить dma
3a. включить uart
============================================================
void DMA1_Channel4_IRQHandler(void)
{
DMA1->IFCR |= DMA_ISR_TCIF4;//очистить флаг окончания обмена.
}
HAL_DMA_Abort
HAL_UART_DMAStop
and recalling the DMA initialisation routine but it still doesn't restart correctly
add
__HAL_USART_CLEAR_OREFLAG(&huart1);
====================================================
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, 3000);
DMA_Cmd(DMA1_Channel1, ENABLE);
1. выключить канал dma
2. записать в CNDTR размер буфера
3. включить dma
при отладке с остановами работаеттолько такой код:
1a. выключить uart
1. выключить канал dma
2. записать в CNDTR размер буфера
2.a записать CCR то что писалось при инициализации
3. включить dma
3a. включить uart
============================================================
void DMA1_Channel4_IRQHandler(void)
{
DMA1->IFCR |= DMA_ISR_TCIF4;//очистить флаг окончания обмена.
}
========================================================
To start another DMA transaction you should program a transaction length. It can be programmed only when a DMA channel disabled. So in your case code might looks like this:
void DMA1_Channel5_IRQHandler(void) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA1_Channel5->CNDTR = UART_PACKET_SIZE; // <--- transaction length
DMA_Cmd(DMA1_Channel5, ENABLE);
}
Or you can use your function uart_receive_dma(), but you should disable a DMA channel prior to calling it.
void DMA1_Channel5_IRQHandler(void) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Cmd(DMA1_Channel5, DISABLE);
uart_receive_dma();
}
Second variant will do same thing as first, but will take much more time.
пятница, 4 августа 2017 г.
EmWin skins for buttons.
#include "DIALOG.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01)
#define ID_BUTTON_1 (GUI_ID_USER + 0x02)
#define ID_BUTTON_2 (GUI_ID_USER + 0x03)
#define ID_BUTTON_3 (GUI_ID_USER + 0x04)
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 20, 10, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 20, 40, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_2, 20, 70, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_3, 20, 100, 80, 20, 0, 0x0, 0 },
};
static BUTTON_SKINFLEX_PROPS _aProps[] = {
// BUTTON_SKINFLEX_PI_PRESSED
{
{GUI_RED, GUI_RED, GUI_DARKRED},
{GUI_LIGHTRED, GUI_RED },
{GUI_RED, GUI_DARKRED },
3
},
// BUTTON_SKINFLEX_PI_FOCUSSED
{
{GUI_DARKRED, GUI_RED, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_ENABLED
{
{GUI_DARKRED, GUI_GRAY, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_DISABLED
{
{0, 0, 0},
{0, 0 },
{0, 0 },
3
},
};
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _CustomSkin
*/
static int _CustomSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
int Id;
GUI_POINT aPoints[3];
GUI_COLOR Color;
BUTTON_SKINFLEX_PROPS aPropsOld[4];
int i;
switch (pDrawItemInfo->Cmd) {
case WIDGET_ITEM_DRAW_BACKGROUND:
Id = WM_GetId(pDrawItemInfo->hWin);
switch (Id) {
case ID_BUTTON_0:
//
// Draw an elliptic button
//
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_YELLOW;
} else {
Color = GUI_RED;
}
GUI_SetColor(Color);
GUI_FillEllipse(pDrawItemInfo->x1 / 2, pDrawItemInfo->y1 / 2, pDrawItemInfo->x1 / 2 - 1, pDrawItemInfo->y1 / 2 - 1);
break;
case ID_BUTTON_1:
//
// Draw a triangle button
//
aPoints[0].x = pDrawItemInfo->x1 / 2;
aPoints[0].y = pDrawItemInfo->y0;
aPoints[1].x = pDrawItemInfo->x1;
aPoints[1].y = pDrawItemInfo->y1;
aPoints[2].x = pDrawItemInfo->x0;
aPoints[2].y = pDrawItemInfo->y1;
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_GREEN;
} else {
Color = GUI_CYAN;
}
GUI_SetColor(Color);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), pDrawItemInfo->x0, pDrawItemInfo->y0);
break;
case ID_BUTTON_2:
//
// Draw a standard button with different colors
//
for (i = 0; i < 4; i++) {
BUTTON_GetSkinFlexProps(&aPropsOld[i], i); // Get default properties
BUTTON_SetSkinFlexProps(&_aProps[i], i); // Set new properties
}
BUTTON_DrawSkinFlex(pDrawItemInfo); // Draw button with new properties
for (i = 0; i < 4; i++) {
BUTTON_SetSkinFlexProps(&aPropsOld[i], i); // Restore old properties to avoid other buttons will be drawn with this properties
}
break;
case ID_BUTTON_3:
BUTTON_DrawSkinFlex(pDrawItemInfo);
break;
}
return 0;
default:
return BUTTON_DrawSkinFlex(pDrawItemInfo);
}
}
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWIN hItem;
int NCode;
int Id;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetSkin(hItem, _CustomSkin);
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
/*********************************************************************
*
* MainTask
*/
//////////void MainTask(void) {
////////// //
////////// // Set flag for automatic use of memory devices. Calling before GUI_Init() makes sure the desktop window uses them, too.
////////// //
////////// WM_SetCreateFlags(WM_CF_MEMDEV);
////////// //
////////// // Initialize GUI
////////// //
////////// GUI_Init();
////////// GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
////////// while (1) {
////////// GUI_Delay(100);
////////// }
//////////}
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01)
#define ID_BUTTON_1 (GUI_ID_USER + 0x02)
#define ID_BUTTON_2 (GUI_ID_USER + 0x03)
#define ID_BUTTON_3 (GUI_ID_USER + 0x04)
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 20, 10, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 20, 40, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_2, 20, 70, 80, 20, 0, 0x0, 0 },
{ BUTTON_CreateIndirect, "Button", ID_BUTTON_3, 20, 100, 80, 20, 0, 0x0, 0 },
};
static BUTTON_SKINFLEX_PROPS _aProps[] = {
// BUTTON_SKINFLEX_PI_PRESSED
{
{GUI_RED, GUI_RED, GUI_DARKRED},
{GUI_LIGHTRED, GUI_RED },
{GUI_RED, GUI_DARKRED },
3
},
// BUTTON_SKINFLEX_PI_FOCUSSED
{
{GUI_DARKRED, GUI_RED, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_ENABLED
{
{GUI_DARKRED, GUI_GRAY, GUI_DARKGRAY},
{GUI_LIGHTGRAY, GUI_GRAY },
{GUI_GRAY, GUI_DARKGRAY },
3
},
// BUTTON_SKINFLEX_PI_DISABLED
{
{0, 0, 0},
{0, 0 },
{0, 0 },
3
},
};
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _CustomSkin
*/
static int _CustomSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
int Id;
GUI_POINT aPoints[3];
GUI_COLOR Color;
BUTTON_SKINFLEX_PROPS aPropsOld[4];
int i;
switch (pDrawItemInfo->Cmd) {
case WIDGET_ITEM_DRAW_BACKGROUND:
Id = WM_GetId(pDrawItemInfo->hWin);
switch (Id) {
case ID_BUTTON_0:
//
// Draw an elliptic button
//
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_YELLOW;
} else {
Color = GUI_RED;
}
GUI_SetColor(Color);
GUI_FillEllipse(pDrawItemInfo->x1 / 2, pDrawItemInfo->y1 / 2, pDrawItemInfo->x1 / 2 - 1, pDrawItemInfo->y1 / 2 - 1);
break;
case ID_BUTTON_1:
//
// Draw a triangle button
//
aPoints[0].x = pDrawItemInfo->x1 / 2;
aPoints[0].y = pDrawItemInfo->y0;
aPoints[1].x = pDrawItemInfo->x1;
aPoints[1].y = pDrawItemInfo->y1;
aPoints[2].x = pDrawItemInfo->x0;
aPoints[2].y = pDrawItemInfo->y1;
if (BUTTON_IsPressed(pDrawItemInfo->hWin)) {
Color = GUI_GREEN;
} else {
Color = GUI_CYAN;
}
GUI_SetColor(Color);
GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), pDrawItemInfo->x0, pDrawItemInfo->y0);
break;
case ID_BUTTON_2:
//
// Draw a standard button with different colors
//
for (i = 0; i < 4; i++) {
BUTTON_GetSkinFlexProps(&aPropsOld[i], i); // Get default properties
BUTTON_SetSkinFlexProps(&_aProps[i], i); // Set new properties
}
BUTTON_DrawSkinFlex(pDrawItemInfo); // Draw button with new properties
for (i = 0; i < 4; i++) {
BUTTON_SetSkinFlexProps(&aPropsOld[i], i); // Restore old properties to avoid other buttons will be drawn with this properties
}
break;
case ID_BUTTON_3:
BUTTON_DrawSkinFlex(pDrawItemInfo);
break;
}
return 0;
default:
return BUTTON_DrawSkinFlex(pDrawItemInfo);
}
}
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWIN hItem;
int NCode;
int Id;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetSkin(hItem, _CustomSkin);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetSkin(hItem, _CustomSkin);
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
/*********************************************************************
*
* MainTask
*/
//////////void MainTask(void) {
////////// //
////////// // Set flag for automatic use of memory devices. Calling before GUI_Init() makes sure the desktop window uses them, too.
////////// //
////////// WM_SetCreateFlags(WM_CF_MEMDEV);
////////// //
////////// // Initialize GUI
////////// //
////////// GUI_Init();
////////// GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
////////// while (1) {
////////// GUI_Delay(100);
////////// }
//////////}
четверг, 3 августа 2017 г.
Add CMSIS-RTOS RTX & CubeMX adapt generated files
This section explains how to add the CMSIS-RTOS RTX real-time operating system.
Setup in STM32CubeMX
In STM32CubeMX ensure that the System Tick Interrupt is set to the lowest priority (which is the highest number).
Configuration tab
- Under System open NVIC Configuration.
- Click on System tick timer and set Preemption Priority to 15 (highest possible value).
- Click OK to close the NVIC Configuration dialog.
Setup in MDK
In MDK, the steps to add the CMSIS-RTOS RTX real-time operating system to a project that is configured with STM32CubeMX are:
Step 1: Add CMSIS-RTOS RTX
- Open the Manage Run-Time Environment window and add CMSIS:RTOS (API):Keil RTX.
Step 2: Configure CMSIS-RTOS RTX parameters
- Open the configuration file RTX_Conf_CM.c from the project window, component group CMSIS.
- Optionally you may change to the Configuration Wizard tab.
- Change the following settings:
- Main Thread stack size [bytes] 1024
- RTOS Kernel Timer input clock frequency [Hz] set to core clock frequency
- Save the file.
Step 3: Add code for CMSIS-RTOS RTX in 'main.c'
- Open the source file main.c from the project window, source group STM32CubeMX:Common Sources and add code lines in the sections USER CODE BEGIN / USER CODE END as shown below:
:
/* USER CODE BEGIN Includes */
#include "cmsis_os.h" // ARM::CMSIS:RTOS:Keil RTX
/* USER CODE END Includes */
:
/* USER CODE BEGIN 0 */
extern uint32_t os_time;
uint32_t HAL_GetTick(void) { // Add HAL_GetTick function for STM32Cube HAL
return os_time;
}
/* USER CODE END 0 */
:
int main(void)
{
:
/* USER CODE BEGIN 1 */
osKernelInitialize (); // Initialize RTOS Kernel for setup
/* USER CODE END 1 */
:
/* USER CODE BEGIN 2 */
osKernelStart (); // Begin thread switching
/* USER CODE END 2 */
:
Step 4: Remove SysTick_Handler in stm32f7xx_it.c
- STM32CubeMX generates a SysTick_Handler that is in-compatible with CMSIS-RTOS RTX. Remove the code for the SysTick_Handler in the source file stm32f7xx_it.c as shown below.
#if 0
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
#endif
Step 5: Build Project in MDK
- Use Project - Build Target to generate the application code.
The source file generated by STM32CubeMX can be accessed in the MDK project window, source group STM32CubeMX:Common Sources. These file require the following modifications.
Changes to 'stm32fxxx_it.c'
CMSIS-Driver and CMSIS-RTOS RTX implement their own interrupt handlers.
- For using CMSIS-RTOS RTX remove the code of the SysTick_Handler.
- For using CMSIS-Driver remove the code of the related Interruption Handler.
- Note
- STM32CubeMX re-generates this file and it is required to remove the interrupt handlers after using Generate Code.
Changes to 'main.c'
- CMSIS-Driver initialize peripherals using dedicated functions that are called by middleware. Initialization code in 'main.c' for the related peripherals is therefore not required and may be removed.
- CMSIS-RTOS RTX requires initialization code. Refer to Add CMSIS-RTOS RTX for detailed information.

