CubeMX and FreeRTOS: Systick

As you know, I'm playing with STM32 and CubeMX autogeneration code tool. I don't like ST HAL libraries generated by CubeMX, but this is my first approach to STM32 MCUs and CubeMX tool lets me have a fully-functional project in minutes. Maybe I will rewrite some HAL drivers in the future, but at the moment I'd like to leave with them.

Now I have to add FreeRTOS and this is very simple with CubeMX. However I have some doubts.

First of all CubeMX strongly suggests to change hw timer for ST HAL, because Systick is already used by FreeRTOS. I understood the problem is with interrupt priority: ST HAL needs the highest priority (because ticks counting must continue during whatever ISR, because some ISR code could wait for some time... how bad!!!); FreeRTOS needs the lowest priority (sincerely I couldn't understand why).

If you don't call ST HAL functions that uses ticks from ISR, you can leave with both modules (ST HAL and FreeRTOS) using Systick. I'm not going to block an ISR waiting for ms, so this limitation is acceptable to me. However I suspect some ST HAL ISR (USB? SD?) call HAL delay functions, so I can't be sure I will respect the limitation.

At the moment, it seems the only solution is to use two different hw timers (systick and another timer) for ST HAL and FreeRTOS. It's a waste of resources, but there isn't another immediate solution.

I know I can rewrite ST HAL drivers to avoid delays in ISR, but this can be done with UART, SPI and similar simple peripherals. But it takes time and anyway I will never rewrite USB or other complex driver.

What is your solution?

Reply to
pozz
Loading thread data ...

luni, 16 decembrie 2019, 02:30:17 UTC+2, pozz a scris:

If you don't have any experience with STM32 chips, then expect much much longer time to have a fully functional project than "minutes". CubeMX or not.

Reply to
raimond.dragomir

Il 16/12/2019 08:01, snipped-for-privacy@gmail.com ha scritto: >> [...]

Oh yes, I know. Anyway starting with a fully-functional project thanks to CubeMX is very good. I use the next time to improve CubeMX code and my question regarding Systick was born from this goal.

Reply to
pozz

luni, 16 decembrie 2019, 10:11:30 UTC+2, pozz a scris:

CubeMX is about the initializations. It's a pitty it doesn't have a "register level" mode. It uses HAL, LL, whatever, so you will need to use these drivers in your application AFTER the CubeMX. Do you understand the init code generated by CubeMX? How much documented is the HAL, LL whatever? How easy it is to cross-reference the HAL, LL to the real user manual of the chip? Do you really know what to do next AFTER the CubeMX generated his code? Or, how easy it is to continue and write your own application AFTER the CubeMX?

You need to answer these questions first. I think it's too early to improve the CubeMX code.

Reply to
raimond.dragomir

Il 16/12/2019 09:31, snipped-for-privacy@gmail.com ha scritto:

I understood LL is somewhat "register level" mode, even if I'm using HAL yet.

Yes, it's not difficult to follow the code with a debug.

I don't know, I will check when I use them. At the moment I'm working on a code already written by someone else.

Build and test. Write the main application.

In my experience, nothing is easy.

Reply to
pozz

First, use systick for FreeRTOS and a different timer for HAL.

Second, you probably will need to rewrite ST drivers to properly use OS facilities instead of idiotic timer-based polling etc. Especially USB, which is incomplete, buggy, and not integrated with OS. I still have to track down and fix periodic dropping of 64-byte packets during USB-CDC transmission to host, aaarrrggg...

Third, you may find ST drivers non-performant due to above issues plus bizarre number of layers and pointers to pointers to static structures.

Hope that helps, Best Regards, Dave

Reply to
Dave Nadler

Both ST and Atmel hardware-builder created code is not worth the trouble needed to debug it.

I'd like instead have honest hardware descriptions.

I lost 3 weeks on clock initialization, as the hardware description did not tell that only one control field can be changed at any one time, or the wait-for-ready functionality does never get ready.

--

-TV
Reply to
Tauno Voipio

I generated a project in LL mode recently and when I looked at the generated C code, it looked very similar to HAL generated code.

Since I have a hard time trying to follow the HAL code, I just use the HAL code which I am semi-familiar with and leave it at that.

Then, of course, use low level register code of my own after things are initialized.

Reply to
boB

What is the real reason to proceed in this way? Does HAL code really use ticks in ISRs, that would block forever if the HAL ticking timer has the lowest priority (as the ticking timer of FreeRTOS)?

Do you know of projects with those drivers rewritten in a better way? Mainly: UART, SPI and I2C.

Same question as before.

Yes I know. At the moment, I'd like to leave with them. Optimization can be done later.

Another question related to STM32 world. What is the main community site? Official ST community appears very bad initially. I posted two times for wrong, because I thought that was a search form, not a new post form.

ST Community website has two sections: Communities, that seem not frequented, and Q&A taht seem much more updated.

I think I have found a bug in MX initialization code. HAL_InitTick() is called two times: first during HAL_Init() and second during SystemClock_Config()/HAL_RCC_ClockConfig() [*].

The first time HAL_InitTick(TICK_INT_PRIORITY) is used. Second time HAL_InitTick(uwTickPrio) is used.

If timebase source is Systick, HAL_InitTick() in stm32l4xx_hal.c updates the variable uwTickPrio. If timebase source is TIM1, HAL_InitTick() in stm32l4xx_hal_tim.c doesn't update uwTickPrio. So the second time HAL_InitTick() is called, the value of uwTickPrio is the initialization value that is an invalid priority.

When HAL_NVIC_SetPriority() is called the second time, an assert is fired if the priority number is invalid.

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t prioritygroup = 0x00;

/* Check the parameters */ assert_param(IS_NVIC_SUB_PRIORITY(SubPriority)); assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));

prioritygroup = NVIC_GetPriorityGrouping();

NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority)); }

[*] I don't know exactly why initialization code needs to initialize ticks two times. I imagine the first time ticks are initialized with the default/startup clock configuration, so ticks can be used *before* clock is configured. After clocks are configured, the ticks are re-initialized again with the final configuration.
Reply to
pozz

The community is helpful but the forum software is pathetic and constantly complained about. ST staff are haphazard about responding to bugs or questions.

As far as a good set of drivers, there are many isolated examples, but not from ST, and of course they are different for different chip families.

ARM Embed claim to have a complete, solid, debugged RTOS and stack (Ethernet, file system, USB, some drivers). I haven't tried it but if I'd known how much time I'd waste with ST stuff maybe I'd have gone that route, but who knows if its really better.

Hope that helps! Best Regards, Dave

Reply to
Dave Nadler

what a pity!

It doesn't really help, anyway thank you.

Most probably I will post some other questions related to ST code in this ng. Please help me, if you can.

Reply to
pozz

Make sure to also post questions on forum:

formatting link

Reply to
Dave Nadler

Yes, this is one of my question.

formatting link

Reply to
pozz

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.