MM32F3277 MicroPython的 mem 函数对于MCU内存访问

举报
tsinghuazhuoqing 发表于 2021/12/25 23:55:48 2021/12/25
【摘要】 简 介: 通过mem32,mem16,mem8可以使得MicroPython向访问数字一样访问MCU中的任意内存。在ARM模型下,所有的寄存器都是基于RAM地址访问,所以原则上,可以通过memxx编...

简 介: 通过mem32,mem16,mem8可以使得MicroPython向访问数字一样访问MCU中的任意内存。在ARM模型下,所有的寄存器都是基于RAM地址访问,所以原则上,可以通过memxx编程,在MicroPython层完成对于MCU中所有的模块的使用。这在内核功能还没有支持的一些特殊的MCU功能的实现,是非常重要的。

关键词 mem32mem16mem8MM32MicroPython

mem内存访问
文章目录
mem函数
初步测试mem
访问MM32F3277
内部专用模块
访问Chip ID
访问IO
总 结

 

§01 mem内存访问


一、mem函数

  在(2021-11-30)有 MindMotion 的SuYong提供的MicroPython以及之前的版本中,都带有mem函数。在 MicroPython 官网上也介绍了如果使用mem函数能够直接对于特定的MCU中的寄存器进行访问,从而加快程序的の执行。

MicroPython v1.16 on 2021-11-29; MB_F3270 with MM32F3277G7P
>>> 
>>> import machine
>>> dir(machine)
['__name__', 'ADC', 'DAC', 'PWM', 'Pin', 'SDCard', 'SPI', 'Signal', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'freq', 'mem16', 'mem32', 'mem8']
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  比如在下面的代码中,使用mem16完成对于STM32GPIOA中的Pin数据寄存器直接方法,可以大大加快运行的速度。

import machine
import stm

BIT14 = const(1 << 14)
machine.mem16[stm.GPIOA + stm.GPIO_ODR] ^= BIT14

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  下面是常用到的python对Pin的操作。其中隐含了一些额外的函数调用支出。

mypin.value(mypin.value() ^ 1) # mypin was instantiated as an output pin

  
 
  • 1

二、初步测试mem

  根据MM32F3277数据手册对于其中内存的分布定义,下表格给出了各个内部资源位置的定义。

▲ 图1.2.2 MM32F3277 内存位置定义

▲ 图1.2.2 MM32F3277 内存位置定义

1、访问FLASH区域

(1)使用mem32访问

  使用mem32访问的时候,地址需要为4的整数倍数,否则会出定义错误。

  访问程序代码:

from machine                import Pin,mem8,mem32,mem16
import utime

for i in range(10):
    print("%04x"%mem32[i<<2])

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  输出代码:

>> Download MicroPython : 22 lines/526 characters.
>> -------------------------------------------------------------------------

20010000
800042d
8000491
8000495
800048d
800048d
800048d
0000
0000
0000
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(2)使用mem8访问

  使用mem8可以按照字节访问内部的FLASH。

from machine                import Pin,mem8,mem32,mem16
import utime

for i in range(10):
    str = ''
    for j in range(16):
        str = str + "%02x "%mem8[i*16+j]

    print(str)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  输出的结果为:

>> Download MicroPython : 25 lines/589 characters.
>> -------------------------------------------------------------------------

00 00 01 20 2d 04 00 08 91 04 00 08 95 04 00 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 99 04 00 08 
8d 04 00 08 00 00 00 00 9d 04 00 08 9d 57 01 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 8d 04 00 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 8d 04 00 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 8d 04 00 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 8d 04 00 08 
8d 04 00 08 8d 04 00 08 8d 04 00 08 8d 04 00 08 
00 00 00 00 8d 04 00 08 00 00 00 00 8d 04 00 08 
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

  对比下载的MicroPython程序,可以看到输出的数据与下载的Flash在0x800000,映射到0x0处的Flash的结果一样的。

  上面的结果使用下面的代码访问是一样的:

for i in range(10):
    str = ''
    for j in range(16):
        str = str + "%02x "%mem8[i*16+j+0x8000000]

    print(str)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

▲ 图1.2.1 MicroPython烧入程序

▲ 图1.2.1 MicroPython烧入程序

2、访问RAM

from machine                import Pin,mem8,mem32,mem16
import utime

for i in range(10):
    str = ''
    for j in range(16):
        str = str + "%02x "%mem8[i*16+j+0x20004000]

    print(str)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(1)读取RAM

  这是0x2000000前面RAM中的内容。

>> Download MicroPython : 25 lines/600 characters.
>> -------------------------------------------------------------------------

40 35 02 08 54 35 02 08 03 00 00 00 94 36 02 08 
a4 36 02 08 14 37 02 08 24 37 02 08 34 37 02 08 
44 37 02 08 54 37 02 08 64 37 02 08 74 37 02 08 
84 37 02 08 b4 36 02 08 c4 36 02 08 d4 36 02 08 
e4 36 02 08 f4 36 02 08 04 37 02 08 94 37 02 08 
a8 37 02 08 bc 37 02 08 e8 37 02 08 14 38 02 08 
90 40 02 08 a0 40 02 08 b0 40 02 08 c0 40 02 08 
d0 40 02 08 00 00 00 00 60 3e 02 08 70 3e 02 08 
80 3e 02 08 10 41 02 08 20 41 02 08 90 41 02 08 
a0 41 02 08 b0 41 02 08 c0 41 02 08 00 00 00 00 
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

  下面是0x20004000 RAM处的内容:

>> Download MicroPython : 25 lines/600 characters.
>> -------------------------------------------------------------------------

aa 78 90 01 b3 70 9b eb ef ea 88 4c 58 d3 fc b4 
1e 7e ba c8 07 62 a9 cb df 67 c0 80 3f 24 f0 14 
c7 fa c6 10 d0 36 b7 bd d9 3b 70 a1 5c 0e aa 75 
91 ec 83 36 c1 19 da bc ac f6 92 4c 00 14 2b ae 
a6 0a c8 44 dc a6 b4 1e e6 f1 a7 81 44 92 ff eb 
05 9d 35 bb 61 91 7f 7f fc a6 d3 34 c5 f9 dd 56 
63 bd 00 21 28 4e 97 e3 e3 f5 09 03 50 51 33 8c 
0f f7 95 65 48 df 73 e5 99 9e 13 20 ea 50 4d 6b 
c6 07 a8 f1 b1 82 c8 e9 a7 a7 ec a7 58 91 51 39 
6f 5b c5 b2 ee 1f 4f 5f bc f7 19 65 81 50 f8 20 
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(2)对于RAM进行写入

from machine                import Pin,mem8,mem32,mem16
import utime

for i in range(10):
    str = ''
    for j in range(16):
        mem8[i*16+j+0x20004000] = i*16+j

for i in range(10):
    str = ''
    for j in range(16):
        str = str + "%02x "%mem8[i*16+j+0x20004000]

    print(str)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

  允许结果如下,可以看到读出的内容是写入的。

>> Download MicroPython : 30 lines/699 characters.
>> -------------------------------------------------------------------------

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 
80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 
90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f 
>>> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

 

§02 访问MM32F3277


一、访问Chip ID

1、一些特殊常量

  根据MM32F3277的数据手册,芯片的MCU,DEBUG_CR,JEDEC_ID的地址,下面访问他们的内容:

from machine                import Pin,mem8,mem32,mem16
from micropython            import const
import utime

mcu_id   = const(0x40007080)
debug_cr = const(0x40007084)
jedec_id = const(0xe00ff000)

print('DEV ID:%04x'%mem32[mcu_id])
print('DEBUG_CR:%04x'%mem32[debug_cr])
print('JEDECID:%04x'%mem32[jedec_id])

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  运行结果:

DEV ID:-33655f19
DEBUG_CR:0000
JEDECID:-f0ffd

  
 
  • 1
  • 2
  • 3

  可以看到,输出的结果与手册中给定的の结果很不一致。

2、UID

  读取 DEVICE ID 数值。

(1)代码

from machine                import Pin,mem32,mem16,mem8
import utime
from micropython            import const

uid_base = const(0x1ffff7e8)

for i in range(12):
    print('%02x'%mem8[uid_base+i])

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(2)输出结果

00
32
4d
4d
48
ff
ff
ff
88
fe
fc
ff

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

二、访问IO

  下面代码反映对于PB2,通过地址直接进行方案,改变他的输出状态。

from machine                import Pin,mem8,mem32,mem16
from micropython            import const
import utime

led = Pin('PB2', Pin.OUT_PUSHPULL)

GPIOA_BASE      = const(0x40040400)
BIT0            = const(1<<2)

while True:

    mem32[GPIOA_BASE+3*4] ^= BIT0
    utime.sleep_ms(100)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

▲ 图2.2.1  通过mem改变LED状态

▲ 图2.2.1 通过mem改变LED状态

三、访问Timer

下面代码是使用mem直接访问Timer的寄存器,来修改PWM输出的频率。

from machine                import PWM,Pin,mem8,mem16,mem32
import utime
import machine
from micropython            import const

led = Pin('PB2', Pin.OUT_PUSHPULL)

pwm0 = PWM(0, freq=10000, duty=500)

APB2PERIPH_BASE         = const(0x40010000)
APB1PERIPH_BASE         = const(0x40000000)

TIM1_BASE               = const(APB2PERIPH_BASE + 0x2C00)
TIM2_BASE               = const(APB1PERIPH_BASE + 0x0000)
TIM3_BASE               = const(APB1PERIPH_BASE + 0x0400)
TIM4_BASE               = const(APB1PERIPH_BASE + 0x0800)

TIM5_BASE               = const(APB1PERIPH_BASE + 0x0C00)
TIM6_BASE               = const(APB1PERIPH_BASE + 0x1000)
TIM7_BASE               = const(APB1PERIPH_BASE + 0x1400)
TIM8_BASE               = const(APB2PERIPH_BASE + 0x3400)

print("Test PWM0.")

for i in range(29):
    print('%d,%04x'%(i, mem32[TIM3_BASE+i*4]))

mem32[TIM3_BASE+11*4] = 0x300

while True:
    led(led()^1)
    utime.sleep_ms(100)

    print("%04x"%mem32[TIM3_BASE+9*4])

    break

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

 

  结 ※


  过mem32,mem16,mem8可以使得MicroPython向访问数字一样访问MCU中的任意内存。在ARM模型下,所有的寄存器都是基于RAM地址访问,所以原则上,可以通过memxx编程,在MicroPython层完成对于MCU中所有的模块的使用。这在内核功能还没有支持的一些特殊的MCU功能的实现,是非常重要的。


■ 相关文献链接:

● 相关图表链接:

文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。

原文链接:zhuoqing.blog.csdn.net/article/details/121626688

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。