打印

[M0+] STM32G070RB Nucleo开发板评测

[仿制链接]
1235|10
跳转到指定楼层
楼主
本帖最终由 zhanzr21 于 2019-4-11 22:02 修正

1.前语

最近ST公司新品不断, 一段时刻没有重视这个再上官网一看: 内容更新许多. 其间之一便是发布了G0系列的产品. ST还联合媒体举行了"旧板换新板"的活动. 开发板我是有许多的, 说实在的许多开发板便是刚开端拿到手领会个新鲜, 之后都被"打入冷宫". 日常作业仍是很繁忙的, 假如朴实的"玩板子", 工程师的确没有许多时刻投入. 可是ST的开发板不同, 很少有被置之不理的. 原因很简略, 由于日常开发测验常常要用到. 尤其是Nucleo系列的开发板, 我常常运用. 在产品的开发初期, 用开发板来验证规划,主意是很便利的.能节约不少时刻. 所以看到"以旧换新"的活动, 我就坚决果断的参加了. 把别的一家的Cortex M0的开发板换了G0的开发板. ST家的Cortex M0的开发板我也有不少,但舍不得拿出来换, 由于仍是要常常用的. STM32G070RB Nucleo的开发板如愿换到手了, 试用了下仍是很喜欢的. 这儿把自己的一些领会写下, 期望能给读者带一点信息.

2. 板子芯片内核-Nucleo/ST/Cortex
就Nucleo开发板自身而言, 最少对我来讲没有什么新鲜感, 乃至有点"审美疲劳". 由于全部Nucleo开发板都差不多, 我最重视的仍是芯片自身.
图 Nucleo-G070RB正面

图 Nucleo-G070RB不和


after_selected_default_config.png (320.7 KB, 下载次数: 4)

after_selected_default_config.png

code_generate_toolchain_type.png (42.57 KB, 下载次数: 5)

code_generate_toolchain_type.png

cubemx_select_f070_nucleo_board.png (420.66 KB, 下载次数: 5)

cubemx_select_f070_nucleo_board.png

cubemx_splash.png (15.46 KB, 下载次数: 7)

cubemx_splash.png

default_board_config_confirm.png (14.65 KB, 下载次数: 6)

default_board_config_confirm.png

en.STM32G0x0_Value_line_LN2050.jpg (34.75 KB, 下载次数: 5)

en.STM32G0x0_Value_line_LN2050.jpg

en.STM32G0x1_line_LN2048.jpg (192.34 KB, 下载次数: 7)

en.STM32G0x1_line_LN2048.jpg

stdout_retarget.png (472.89 KB, 下载次数: 4)

stdout_retarget.png

stm32g0_series_feature_matrix.png (265.88 KB, 下载次数: 4)

stm32g0_series_feature_matrix.png

usart_7bit_badcode.png (77.25 KB, 下载次数: 2)

usart_7bit_badcode.png

usart_7bit_to_8bit.png (57.21 KB, 下载次数: 3)

usart_7bit_to_8bit.png
沙发
 楼主 | 2019-4-11 22:04 | 只看该作者
不过仍是烦琐几句, 由于也不是每个人都对这板子很熟. 要是大学生,或许刚入行的工程师, Nucleo G070RB开发板是他们第一个ST开发板也有或许的. Nucleo开发板是ST公司官方推出的一系列简配版开发板. 依据方针芯片的封装, 有Nucleo32, Nucleo64, Nucleo144几种. 为什麽说是"简配版", 由于Nucleo系列的开发板都是十分简略. 基本上便是"Debugger + 方针芯片 + 衔接器". 有些Nucleo板子上还有方针芯片的USB接口/以太网接口等等. 简略有简略的优点, 便是把简直全部芯片引脚与资源都敞开出来了. 作为工程师, 你假如把Nucleo开发板运用起来, 对功率进步十分大. 除了"简配版"的Nucleo系列之外, ST官方还有"Discovery"与"Eval"系列的开发板, 那些开发板都有不少外设, 更适合"玩". 我也有不少"Discovery", "Eval"开发板, 实话说基本上没什么时刻"玩". 当然我个人是期望多一点时刻来"玩"这些开发板. 今后有时刻再来细说. 这儿咱们把论题收一收, 现在首要谈论Nucleo F070RB开发板.
这次推出G0系列, 现实上有三个系列:
STM32G070:                        低成本系列
STM32G071:                        干流功用系列                       
STM32G081:                        安全系列

图 G0系列功用图



图 G070系列产品



图 G071, G081系列还有行将上市的其他系列



上图中也看的出, G070是现在推出最低端的系列(立刻会有更低端的系列推出), G0x1的许多高档功用:DAC, USBPD, USB, CAN, 安全存储, AES硬件加速在G070上没有的.
尽管如此, G070系列仍是有如下亮点:
1. 90nm工艺, F0系列是180nm工艺. 之前的L4系列也是用的90nm工艺. 这个对功耗影响很大, 能够说G0系列至少能够到达L4系列等级, 可是功用上G0系列对标的是F0系列. 能够说G0是F0的低功耗晋级版别.
2. Cortex M0+内核, 这个关于F0的Cortex M0而言是晋级. 其实STM之前的L0系列也是Cortex M0+. 只能说G0系列首要是用来代替F0系列的, 所以也算晋级.
3. G0x0与G0x1是Pin2Pin兼容的, 所以开发者依据产品的详细功用需求在硬件规划上能够灵敏替换.  


板凳
 楼主 | 2019-4-11 22:09 | 只看该作者
3.Demo1: 运用CubeMX生成工程

下面来领会一下运用CubeMX生成第一个工程: Hello World + Blink.
CubeMX最近又有了很大的改版, 从4.x晋级到5.x. 从个人视点来讲, 这个东西还有很大的进步空间. 不过横向比较的话, 现在ST在这方面做的是最好的了. 我常常运用它, 快速图形化生成工程, 装备功用. 能够说由于CubeMX的存在, STM32系列芯片增色不少. 由于时刻, 人力是十分名贵的.
装置CubeMX就不多说了, 很简略的操作. 直接翻开CubeMX, 这儿有一个吐槽点, 便是每次翻开强制下载最新的硬件描绘信息, 个人认为应该按需下载:

图 CubeMX翻开后的强制下载最新信息窗口


网速好的话一会就下载完了, 要是知道板子类型的话运用左面的过滤器很快就可找到Nucleo F070RB板子模板. 运用芯片作为模板也能够, 仅仅用板子模版有一些现成的装备可运用. 自己的准则一贯便是:节约时刻,快速干活.


图 挑选开发板模板

接下来问你是否运用默许装备, 个人认为这也是剩余的一问, 假如运用自定义装备, 直接选芯片还选板子干什么.


图 默许装备承认窗口

之后总算到了项目修正阶段. 由于现已运用了默许装备, 所以只需求小小修正即可.


图 项目修正窗口

留意这儿有个小坑, 默许装备USART运用7bit通讯形式. 假如不留意同步修正调试东西的装备那么运转后输出便是乱码. 当然也能够修正调试东西的装备, 可是仍是依照惯例思想将串口改为8bit形式为好.


  • 图 依照7bit装备初初的乱码

依照惯例思想这儿改成8bit形式:


图 惯例思想的8bit装备


7bit, 9bit这些形式在实践工程中的确有用到的场合, 如仅仅传输0-127的数据时用7bit能够进步速率, 主从组网时运用9bit多一个操控位. 还有些芯片与东西能够支撑最低5bit形式, 理由便是32个方位能够传输A-Z的字母集了. 可是默许装备7bit形式感觉是成心给工程师出附加题的节奏.
其他外设视乎需求而装备, 自己还装备了ADC, GPIO等外设. 这儿不逐个胪陈. 后边会给出参阅规划的下载地址. 全部装备完毕后挑选代码生成输出类型, 自己运用Keil MDK, 读者按需挑选. 最终点击Generate Code就可生成工程结构.


地板
 楼主 | 2019-4-11 22:11 | 只看该作者


图 挑选代码工程输出类型

假如第一次翻开G0系列的工程, Keil MDK还会让你下载一个DFP. 依照提示操作即可, 总归工程自动化程度的进步也是有价值的, 价值便是装置许多支撑包. 整体而言是值得的. 生成的工程直接就能够编译下载运转了, 可是要看出点作用来还得加几句, 自己增加的是打印ADC的采样值, 还有LD4闪耀.别的还要重定向USART2到pritnf.


图 重定向串口到printf


在主文件中增加这个函数:
  1. int stdout_putchar (int ch)
  2. {
  3.         uint8_t c = ch;
  4.         HAL_UART_Transmit(&huart2, &c, 1, 1);
  5.         return ch;
  6. }
仿制代码

其他代码不赘述, 感兴趣的直接下后文代码. 留意假如你的用户代码要防止下次自动生成代码被掩盖的话, 要加在这种宏之间:
  1.   /* USER CODE BEGIN 2 */
  2.         HAL_ADC_Start_DMA(&hadc1, (uint32_t*)g_adc_buf, sizeof(g_adc_buf)/sizeof(g_adc_buf[0]));
  3.         printf("Clock:%u Hz\n", SystemCoreClock);
  4.   /* USER CODE END 2 */
仿制代码

到这儿就编译下载运转看成果了. 全部代码都在后文有下载衔接.


5
 楼主 | 2019-4-11 22:14 | 只看该作者
4.Demo2: MPU运用,Privileged与Unprivileged

G0系列首要是用来代替F0系列的产品, 所以从Cortex M0到Cortex M0+算是一个晋级. Cortex M0与Cortex M0+的差异很纤细, 许多不留意细节的工程师或许还说不出来两者到底有什么不同. 其实ARM公司最初推出Cortex M0的初衷便是替换8bit, 16bit的产品, 可是许多商场的改动便是嵌入式软件复杂度一向在增加. 所以Cortex M0被删去的一些功用在Cortex M0+上又补回来了. 当然其间许多Cortex M0+新增的功用都是Optional, 即可完成也可不完成. 对规划软件的工程师而言Cortex M0+相关于Cortex M0的改动有如下几点比较重要:
  • 1. 流水线从三级变成了两级, 这是为功耗与中止响应速度而考虑的改善
  • 2. VTOR可选, Cortex M0的中止向量是不能有偏移量的, 这点规划过Bootloader的程序员会感触很深.
  • 3. MPU可选, 做过RTOS的使命间阻隔的程序员会感触很深.
  • 4. 两级CPU权限:privileged和unprivileged两种权限状况. Cortex M0也有这两种权限, 仅仅两种权限彻底相同, 所以等于没有.

这儿做个Demo展现一下MPU与两级内核状况的运用. 规划意图: 有一个数组, 在用户态仅仅答应读, 在内核态可读可写. 这种规划在Cortex M0上基本上不或许. 在Cortex M0+的芯片如STM32G0F70上, 运用MPU和CPU权限能够容易做到.
首要声明数组,装备MPU, 留意用的是数组声明是肯定定位:
  1. #define ARRAY_ADDRESS_START    (0x20002000UL)
  2. #define ARRAY_SIZE             MPU_REGION_SIZE_256B
  3. #define ARRAY_REGION_NUMBER    MPU_REGION_NUMBER3


  4. uint8_t PrivilegedReadOnlyArray[32] __attribute__((at(ARRAY_ADDRESS_START)));

  5. void MPU_Config(void) {
  6.   MPU_Region_InitTypeDef MPU_InitStruct = {0};

  7.   HAL_MPU_Disable();

  8.   /* Configure RAM region as Region N°0, 256KB of size and R/W region */
  9.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  10.   MPU_InitStruct.BaseAddress = EXAMPLE_RAM_ADDRESS_START;
  11.   MPU_InitStruct.Size = EXAMPLE_RAM_SIZE;
  12.   MPU_InitStruct.AccessPermission = portMPU_REGION_READ_WRITE;
  13.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  14.   MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  15.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  16.   MPU_InitStruct.Number = EXAMPLE_RAM_REGION_NUMBER;
  17.   MPU_InitStruct.SubRegionDisable = 0x00;
  18.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  19.   HAL_MPU_ConfigRegion(&MPU_InitStruct);

  20.   /* Configure FLASH region as REGION N°1, 1MB of size and R/W region */
  21.   MPU_InitStruct.BaseAddress = EXAMPLE_FLASH_ADDRESS_START;
  22.   MPU_InitStruct.Size = EXAMPLE_FLASH_SIZE;
  23.   MPU_InitStruct.Number = EXAMPLE_FLASH_REGION_NUMBER;

  24.   HAL_MPU_ConfigRegion(&MPU_InitStruct);

  25.   /* Configure Peripheral region as REGION N°2, 512MB of size, R/W and Execute
  26.   Never region */
  27.   MPU_InitStruct.BaseAddress = EXAMPLE_PERIPH_ADDRESS_START;
  28.   MPU_InitStruct.Size = EXAMPLE_PERIPH_SIZE;
  29.   MPU_InitStruct.Number = EXAMPLE_PERIPH_REGION_NUMBER;
  30.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

  31.   HAL_MPU_ConfigRegion(&MPU_InitStruct);

  32.   /* Enable MPU (any access not covered by any enabled region will cause a fault) */
  33.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
  34. }

  35. void MPU_AccessPermConfig(void) {
  36.   MPU_Region_InitTypeDef MPU_InitStruct = {0};

  37.   HAL_MPU_Disable();

  38.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  39.   MPU_InitStruct.BaseAddress = ARRAY_ADDRESS_START;
  40.   MPU_InitStruct.Size = ARRAY_SIZE;
  41.   MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RW_URO;
  42.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  43.   MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  44.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  45.   MPU_InitStruct.Number = ARRAY_REGION_NUMBER;
  46.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  47.   MPU_InitStruct.SubRegionDisable = 0x00;
  48.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  49.   HAL_MPU_ConfigRegion(&MPU_InitStruct);

  50.   /* Enable MPU (any access not covered by any enabled region will cause a fault) */
  51.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
  52. }
仿制代码
主函数中调用上述函数以使能MPU, 而且切换至用户状况:
  1. MPU_Config();
  2.   MPU_AccessPermConfig();       
  3.   __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_MAIN);  
  4.   __ISB();
仿制代码
接下来试验读写权限:

  1. printf("%s %u\n", __func__, __LINE__);
  2.                 printf("%s %u %02X\n", __func__, __LINE__, PrivilegedReadOnlyArray[0]);
仿制代码
这句没缺点, 仅仅读.
这句就会引起HardFault, 由于在用户状况这个数组是不答应写的.

  1. PrivilegedReadOnlyArray[0] = (uint8_t)HAL_GetTick();
  2.                 printf("%s %u %02X\n", __func__, __LINE__, PrivilegedReadOnlyArray[0]);
仿制代码
那么要写怎样办?
答案便是运用SVC指令进入内核权限.

  1. asm_svc_2(HAL_GetTick());               
  2.                 printf("%s %u %02X\n", __func__, __LINE__, PrivilegedReadOnlyArray[0]);
仿制代码
留意asm_svc_2这个是汇编语言写的函数, 要放在别的的.s文件中,概况直接看后文的代码下载衔接.

  1. ;Supervisor Call 2
  2.         ALIGN
  3. asm_svc_2 FUNCTION   
  4.         EXPORT asm_svc_2
  5.         SVC #2
  6.         bx lr       
  7.         ENDP
仿制代码
留意要将SVC_Handler的声明改成有参数输入, 生成的代码是没有参数输入的. 依照AAPS的调用规约, 这个函数能够有输入参数. 为了求简洁, 没有区别SVC号, 实践工程中这样就比较糟蹋SVC号了.

  1. void SVC_Handler(uint32_t input){
  2.         PrivilegedReadOnlyArray[0] = (uint8_t)input;
  3. }
仿制代码
这样就能够到达规划意图了.

6.参阅与下载

ST官方G0系列产品页面 https://www.st.com/en/microcontrollers-microprocessors/stm32g0-series.html
本文全部代码, 留意每个试验一个branch: https://github.com/zhanzr/stm32g0-demo.git




6
 楼主 | 2019-4-11 22:16 | 只看该作者
@巧克力娃娃 良久没有发贴了, 假如想用相册图片, 一次性上传后, 主贴上没用到的图片都会自动当附件显现. 这个怎样破?
7
| 2019-4-12 11:09 | 只看该作者
zhanzr21 宣布于 2019-4-11 22:16
@巧克力娃娃 良久没有发贴了, 假如想用相册图片, 一次性上传后, 主贴上没用到的图片都会自动当附件显现. 这 ...

我不太懂!   @21ic小喇叭  你知道吗?

谈论

zhanzr21 2019-4-12 13:22 回复TA
@21ic小喇叭 :没有操作成功,你帮助操作下,这些是上传到某相册,后边回帖会用到,不能彻底删去。便是不想显现在首贴下(除了自动修正插到原文中的之外). 
21ic小喇叭 2019-4-12 13:11 回复TA
从图片那里显现的附件删掉就行了 
8
| 2019-6-30 10:46 | 只看该作者
牛掰,回帖支撑楼主!

谈论

zhanzr21 2019-6-30 22:00 回复TA
谢谢支撑, 对这方面的研讨一向没有停, 仅仅贴子没有更新了. 一定会找时刻把新的内容收拾发出来的. 
扫描二维码,随时随地手机跟帖
您需求登录后才能够回帖 登录 | 注册

本版积分规矩

我要发帖 投诉主张 创立版块 请求版主

快速回复

您需求登录后才能够回帖
登录 | 注册
高档形式

论坛热帖

封闭

抢手引荐上一条 /6 下一条

在线客服 快速回复 回来顶部 回来列表