cancel
Showing results for 
Search instead for 
Did you mean: 

Low Layer Library, first impressions

Posted on September 18, 2015 at 01:12

As announced by Jasmine in https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/DispForm.aspx?ID=57714&RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fHAL%20gpio%20libary%20code%20bug&Source=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex%5Fmx%5Fstm32... , the Low Layer ehm API is available in the current 'L4xx Cube

http://www.st.com/web/en/catalog/tools/PF261908 - and it's not even ''next week''! 🙂 A whopping 200MB zip, for those who are curious; although the LL-related content is one order of magnitude less (and the vast majority of it are the examples). For real content, look into STM32Cube_FW_L4_V1.1.0\Drivers\STM32L4xx_HAL_Driver\Inc\, filenames of the stm32l4xx_ll_***.h style (i.e. containing ''ll''); there are two more files in ..\Src, too. Documentation - portions of both STM32Cube_FW_L4_V1.1.0\Documentation\STM32CubeL4GettingStarted.pdf and the doxygen-autovomited STM32Cube_FW_L4_V1.1.0\Drivers\STM32L4xx_HAL_Driver\STM32L486xx_User_Manual.chm - does not depart from the style and quality of the rest of Cube. Examples in STM32Cube_FW_L4_V1.1.0\Projects\STM32L476RG-Nucleo\Examples_LL\. . An excerpt from the ''blinkey'' example, to get the feeling of it (doxygen-style comment/headers omitted):

int
main(
void
)
{
/* Configure the system clock to 80 MHz */
SystemClock_Config();
/* -2- Configure IO in output push-pull mode to drive external LED */
Configure_GPIO();
/* Toggle IO in an infinite loop */
while
(1)
{
LL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
/* Insert delay 250 ms */
LL_mDelay(250);
}
}
__STATIC_INLINE 
void
Configure_GPIO(
void
)
{
/* Enable the LED2 Clock */
LED2_GPIO_CLK_ENABLE();
/* Configure IO in output push-pull mode to drive external LED2 */
LL_GPIO_SetPinMode(LED2_GPIO_PORT, LED2_PIN, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(LED2_GPIO_PORT, LED2_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinSpeed(LED2_GPIO_PORT, LED2_PIN, LL_GPIO_SPEED_LOW);
LL_GPIO_SetPinPull(LED2_GPIO_PORT, LED2_PIN, LL_GPIO_PULL_NO);
}
__STATIC_INLINE 
void
SystemClock_Config(
void
)
{
/* MSI configuration and activation */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
LL_RCC_MSI_Enable();
while
(LL_RCC_MSI_IsReady() != 1) 
{
};
/* Main PLL configuration and activation */
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2);
LL_RCC_PLL_Enable();
LL_RCC_PLL_EnableDomain_SYS();
while
(LL_RCC_PLL_IsReady() != 1) 
{
};
/* Sysclk activation on the main PLL */
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
while
(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) 
{
};
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
/* Set systick to 1ms in using frequency set to 80MHz */
/* This frequency can be calculated through LL RCC macro */
/* ex: __LL_RCC_CALC_PLLCLK_FREQ(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, LL_RCC_MSIRANGE_6), 
LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2)*/
LL_Init1msTick(80000000);
/* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
LL_SetSystemCoreClock(80000000);
}

Correct me if I am wrong, but it's essentially a bunch of macros/static inline functions, barely doing anything else than renaming simple register accesses. Now I completely fail to understand the reason to do that, so there must be something wrong with me. JW #grammer-nazis
21 REPLIES 21
mikael239955_stm1_st
Associate III
Posted on September 18, 2015 at 01:46

Nothing wrong with you, it's just one of ST's repeating disasters!

I ask in vain to my self what kind of problem do ST have not able

to understand what a clean, simple,consistent well documented set

of, or one definition file stands for and is to a developer?.

mikael239955_stm1_st
Associate III
Posted on September 18, 2015 at 01:46

if you by accident found one in that 200MB zip pile let me know!

Posted on September 18, 2015 at 02:10

Honestly I did try to reason with them, but didn't seem to get a lot of traction, at this point it's all going to have to collapse under it's own weight. Someone there is going to have to have some sort of epiphany, as the way things are going it's just going to get more unmaintainable.

I'm going to join the Jan on the Dark Side, and tinker at the register level.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carl2399
Associate II
Posted on September 18, 2015 at 05:37

I'm a register level tinkerer - that way all I need is my code and the Programmers Reference Manual - there is no intermediate convenience / magic / interpretation.

It's a bit slower to start with, but quickly gains traction as you build up your own PAL (Personal Abstraction Layer). 

Five years later, I spend a minimum amount of time dealing with registers, the majority of the time being spent on developing the end user applications.

Posted on September 18, 2015 at 06:12

I spent may of my formative years writing in assembler, building libraries of functions, the register stuff is not particularly alien to me, the SPL has just represented a clean abstraction that's served very well.

The thing I do observe is some people claiming they are doing things more efficiently while using dozens of load-store, or RMW type operations, that the compiler can't fold.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
John F.
Senior
Posted on September 18, 2015 at 09:09

OK. I started with the 1802 (a PDP 8 on a chip) in assembler and working out the offsets for jumps by hand. All the same, I don't want to go back there!

Not having seen the ''Low Level'' stuff I thought it

had

to be an improvement on HAL. Now I think differently.

I have a question about middleware (USB / SD card etc. ...).

Can anyone explain exactly where the split is between third party (say Keil for example) middleware and the code ST produces. As far as I understand, Keil middleware now depends on ST drivers ... but if they all depend on HAL and I don't want anything to do with HAL where does that leave me?

I've googled all over trying to understand this and guidance from Keil seems to be use HAL or write your own drivers. I really want to understand this. Please help!

e1369008
Associate II
Posted on September 18, 2015 at 10:02

I am very sorry for the off-topic post, but a certain person whom we all love really needs to read

http://englishplus.com/grammar/00000227.htm

.

AvaTar
Lead
Posted on September 18, 2015 at 11:32

> I am very sorry for the off-topic post, but a certain person whom we all love really needs to read

http://englishplus.com/grammar/00000227.htm

.

 

As a saying in my native language goes : ''You have only one chance to make a first impression.''

Going back to topic, I'm also in conflict of switching to register level hacking, or switching to a different vendor alltogether.

I think/fear that not until big company with serious investments in Cortex M devices backing away from Cube and ST, that epiphany in ST's leadership will happen.

carl2399
Associate II
Posted on September 18, 2015 at 11:52

Definitely agree with Clive on not underestimating the power of modern compilers. I regularly look at the extended assembly listing of my application (pretty easy using the GCC compiler), and just marvel at what gets produced!! More than 9 times out of 10 I would be hard pressed to better the result.

What's nice about starting at the register level is that a c++ wrapper can make for neat code structure. With static allocation of classes (all classes defined at compile time), the output is practically indistinguishable from c, but at the source code level there's no comparison to the elegance that can be achieved.  I'm by no means a c++ wizard, using mainly a ''structure with functions'' approach, but have been gradually adding virtual functions as a way to make for nice Application Layer derived classes.