问题标签 [samd21]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
arm - SAMD21 加密固件
我正在研究 SAMD21,但现在我想实现固件崩溃的可能性。在 SAMD21 上可以吗?我发现这个 pdf 这正是我想要做的第 36 页,但这适用于 SAM3/4 AT02333
我用谷歌搜索,但我没有找到 SAMD21,有人有文档或源代码教程吗?我的想法是用 AES128 加密我的固件,所以我知道我需要在引导加载程序中创建实现它,但我从来没有这样做过......
visual-studio - 连接 DP 时出错:无法读取 IDR-无法建立连接,因为目标机器主动拒绝它
我可以第一次对这个项目进行编程和调试。但问题是我无法重新编程或再次调试它。芯片上没有引导加载程序。与该芯片通信的唯一方法是 SWD。作为调试器,我使用的是 Atmel ice。微芯片是 SAMD21E16B-U。该项目由Atmel Start创建。Visual Studio 用作导入项目的 IDE。
再次调试后,错误为:
- 问题可能是因为设置。我不确定我错过了什么。我按照visualGDB 网站导入了这个项目。
- 我检查了电源连接。
- visualgdb 调试设置上没有“重置下连接”选项。但是,该选项在 STM 芯片上可用。
如果你能指导我如何重新编程这个芯片,我真的很感激?或者我应该寻找哪些信息。提前感谢您提供任何有用的建议。
caching - 为什么非连续加载更快,即使缓存未命中惩罚保证为零?
背景:
我用 C 编写了一个函数并用arm-none-eabi-gcc
(7-2018-q2-update) 编译它。为循环体生成的汇编代码看起来每次迭代需要 20 个周期,包括 2 个等待状态,用于加载操作从非易失性程序存储器访问常量数据。
但是,我的 MCU 的 NVM 控制器缓存说缓存未命中惩罚保证为零,所以我不确定为什么它不能为两个 NVM 加载操作预取数据。因此,我认为循环每次迭代应该花费 18 个周期。
不幸的是,测量的性能与预期的性能有很大的不同。如果我改变了int8_t increment
并且int16_t patch_data_i
两者都是int32_t
,那么 GCC 会以稍微不同的顺序有效地生成相同的指令。我们称这个版本为 (b)。
有趣的是,版本 (a) 每次迭代需要 21 个周期,而版本 (b) 每次迭代需要 20 个周期!
这种性能差异是高度可重复的。我通过改变版本 (a) 和版本 (b) 的 (5, 6, 7, 8) 之间的迭代次数来非常精确地测量它。泰克 465 示波器在固定 B 扫描设置下的定时测量:
(这个循环体的性能至关重要,因为它执行 8 次迭代,并且每 2000 个时钟周期调用一次这个函数。对于我的应用程序,即使这个单周期差异也大约占总 CPU 时间的 0.5%。)
我的问题有 4 个部分:
- 这里发生了什么?
- 为什么版本 (a) 需要 21 个周期而版本 (b) 需要 20 个周期?
- 为什么两个版本都不占用 18 个周期?
- 除了尝试组装操作的随机排列和测量示波器上的所有内容之外,是否有任何可能的方法来准确预测 Atmel SAMD21 微控制器上 RAM 和 NVM 的访问延迟?
(对这 4 部分中的任何 1 部分的答案将不胜感激。)
源代码(版本一)
源代码(版本 b)
生成的程序集(版本 a)
生成的程序集(版本 b)
我对生成程序集的解释(版本 a)
我已经为每种情况写出了我对生成的程序集的“解释”。这部分可能是不必要的,但我认为它也可以包括它,因为它帮助我理解(a)和(b)之间的区别。如上所述,循环前后的部分是相同的。我能看到的唯一显着区别是两个版本以稍微不同的顺序执行相同的指令。特别是,版本 (b)(每次迭代需要 20 个周期)具有零个连续加载/存储操作实例、零个连续加载/加载操作实例和零个连续存储/存储操作实例。(记录在案的每个加载操作的等待状态数在括号中注释:1 个等待状态将由 表示// ^ ldrb [1]
。)
我对生成程序集的解释(版本 b)
平台信息
微控制器是 Atmel/Microchip
AT91SAMD21G18A
。架构是 ARMv6-M。
微架构是 ARM Cortex-M0+。
我的 MCU 内核的主时钟频率是 48 MHz。
在 48 MHz 时,如果高速缓存被禁用,SAMD21 [非易失性] 程序存储器需要 1 个等待状态。
在 48 MHz 时,SAMD21 SRAM 需要零等待状态。
但是,我看不出有什么理由可以更快地从 RAM 执行代码。我相信 NVM 数据路径与 RAM 数据路径是分开的,因此从 NVM 获取的指令永远不应与从 RAM 获取的数据竞争(我不是 100% 确定这一事实,但我认为这是真的。)。因此,如果 NVM 控制器缓存按文档说明工作,那么从 NVM 运行此循环似乎几乎肯定会比从 RAM 运行此循环更快。
- SAMD21 有一个 64 字节的高速缓存,用于访问非易失性存储器。
- NVM 控制器缓存“是一种直接映射的缓存,实现了 8 行 64 位(即 64 字节)”。
- NVM 控制器缓存在
NO_MISS_PENALTY
模式下启用。 - 这是
NO_MISS_PENALTY
模式的数据表描述:“NVM 控制器(缓存系统)不会在缓存未命中时插入等待状态。提供最佳系统性能。” - 数据表没有提供有关
NO_MISS_PENALTY
模式的更多信息。
c - 在 samd21e15b 上使用 Systick
我第一次使用 Systick 使用 samd21e15b,所以我的目标是能够计算延迟之间的时间。所以这就是我尝试做的
所以我设置SysTick->LOAD = 0x7A11FFul
是因为我的 CPU 以 8Mhz 运行并且我想要 1s 滴答声,所以来自这个数学
N = (SysTick 延迟时间/系统时钟周期) - 1
=(SysTick 延迟时间 * 系统时钟频率) - 1
= (1s * 8MHz) - 1 = 8M - 1 = 7,999,99
因此,如果我的 cpu 以 8MHz 运行,我每 125ns 有一个 cpu 周期,对吗?但是如果我检查temps
变量我有一个311
延迟 1s 后的值,我不明白这个值
c++ - __libc_init_array crashes when jumping to constructor ARM SAMD21G18
I have a C++ toolchain for the ARM chip SAMD21g18 and I have just recently implemented the __libc_init_array function, so that global C++ objects have their constructors called before main().
I am using the code shown here: https://embeddedartistry.com/blog/2019/04/17/exploring-startup-implementations-newlib-arm/
And I have added the following two sections to my linker script:
When debugging a sample project, I see in the debugger that the "count" variable before the last for loop in the function, has value 1, which means the compiler must have found one constructor. I have used arm-none-eabi-objdump to check the section, and it has indeed size 4 (meaning one pointer was added to the section).
However, when the CPU tries to jump to that constructor function, it crashes (in gdb, an exception is raised). I looked at the memory address of the pointer, with the debugger, and it was a very high address, starting at 0xEXXXXXXX, but I think it's an incorrect address becasue in my linker script I Have not those addresses assigined to any function. My linker script is basically this: https://github.com/ataradov/mcu-starter-projects/blob/master/samd21/linker/samd21j18.ld
What could be going on? Is the init() function important for this or, as I Have done, can it be commented? I don't know where that function was supposed to come from nor my toolchain was finding it.
c++ - C++ 放置类的新对齐方式(在 SAMD21 微控制器上)
我正在开发一个在 SAMD21 微控制器上运行的应用程序。对于那些不熟悉 SAMD21 的人,它包含一个 ARM Cortex-M0+ 处理器。我使用的特定型号有 32 kB 的 RAM。我的应用程序运行到了 32 kB 的限制,所以我一直致力于优化代码以使用内存。
我一直在进行的一项优化是减少堆碎片。例如,我可能有如下场景:
在上面的示例中,当实例化 时my_third_obj
,内存分配器可能会尝试将其放置在最初由 使用的空位置my_obj
。但是,如果my_third_obj
不适合该位置,则内存分配器将简单地在堆顶部分配更多空间并移动堆指针。这会在原来的位置留下一个“洞” my_obj
(稍后可能会被其他对象填充),但这会产生堆碎片。
在我的特定应用程序中,我已确定在任何时间点我都只需要一个 A、B 或 C 类的活动实例。正因为如此,我正在考虑创建一个内存块来保存任何这些类的当前实例,并简单地使内存块与最大的类一样大,以便它可以容纳任何类。这将减少堆碎片,因为内存中总会有一个特定的位置来分配这些特定的类。
这是我在想的一个简单示例:
我从来没有在我之前编写的代码中真正使用过placement new ,但我认为它在我目前的情况下会很有用。我的主要问题是:鉴于我已经列出的示例,我是否需要以任何方式更改代码来处理对齐问题?类 A、B 和 C 都有不同的成员变量和不同的大小。这段代码会“工作”,还是我需要做一些特别的事情来处理内存对齐?
谢谢!
c - SERCOM (USART) 驱动程序,用于 ATSAMD21 的连续读写
我使用 ATSAMD21 微控制器作为从机,它通过 UART 连接到主 MCU(ESP32)。操作系统 - 适用于 ATSAMD21 - FreeRTOS (IDE- MPLAB) 和适用于 ESP32 (FreeRTOS)。
我在 SAMD21 控制器中的应用之一是以连续方式在“while”循环中读取和写入。对于前-
注意 - 这里的 'ch' 和 'th' 是 char[]。我在这里面临的问题 - 在阅读时不应等待中断,而应执行下一条指令,即“写入”。但在这里它等待主控制器(ESP32)向 SAMD21 发送任何字符,然后它执行下一个“写入”操作并再次等待下一条消息被读取。
我已经在驱动层改变了一些东西——
在这里,我将第 370 行从 -
至-
这样我的问题就解决了,但我一次只能获取一个字节的数据。如果我发送超过 1 个字节,则它正在获取一系列最后的数据。
在这种情况下,如何以连续方式运行我的功能以通过 UART 进行读写。
memory - 如何将链接描述文件从 samd21j18a 更改为 sam-ba 的 samd21e16b?
我正在尝试更改 sam-ba (sam bootloader assistant) 正在使用的链接器脚本。班轮脚本由 Atmel Corporation(tcl_lib 和 applet)为 samd21j18a 编写。根据数据表,samd21e16b Sram 为 8 kB,闪存为 64 kB。根据文档,我需要更改
- appletAddr 和 appletMailboxAddr 相应地在 tcl_lib 中,基于选择的设备和 SAM-BA 引导加载程序占用的 SRAM。
- 为 SAMD21E16B 和最新的 ASF 定制 ASF SAM-BA Applet 链接器脚本。我需要更新基于所选设备的部分,以及 SAM-BA 引导加载程序占用的 SRAM 大小。
您是否有任何资源有助于理解用于定制芯片 (samd21e16b) 的链接器脚本中的这些信息?
什么是 appletAddr 和 appletMailboxAddr?
他们如何写 sram 大小:
tcl_lib:
小程序:
c++ - 使用 Arduino Zero 的端口操作的低级位移寄存器类
我目前正在尝试为 Arduino Zero(基于 SAMD21 Cortex M0)编写一个低级位移寄存器(74HC595)。
我已经完成了一个看起来像这样的更高级别的课程:
位寄存器.h
位寄存器.cpp
问题是我必须在级联中将它与许多寄存器一起使用,该shiftOut2
方法(基于 Arduino 的 shiftOut
方法)非常慢(我认为是由于 multi digitalWrite
)。
因此,基于此SAMD21 Cortex M0 教程和 Arduino 零引脚图(如下),我尝试创建一个较低级别的移位寄存器类。
我目前面临的问题是我无法重写我的shiftOut2
方法的全部内容,因此对于我的测试,我必须直接在方法的主体中硬写端口号。
我将我的寄存器连接到 Arduino 的引脚 10、11 和 12,它们是 SAMD21 端口 18、16 和 19。
我班级的代码(有效)如下:
LowBitRegister.h
与BitRegister.h
(类名和类构造函数名除外)相同。
低位寄存器.cpp
如您所见,我无法重写的唯一部分是:
和
如果您有解决我问题的想法,我将很乐意阅读。
谢谢!
modbus - MODBUS RTU RS485 over atmel studio 中的 samd21 微芯片设备
我正在尝试通过 samd21 微芯片微控制器实现 modbus rtu rs485,但无法获得任何相关参考。有人可以指导我如何做到这一点吗?任何建议都将非常受欢迎。