[LKS32 软件] LKS32AT085评测+DSP评测第二篇

[复制链接]
 楼主| zhanzr21 发表于 2022-8-17 19:00 | 显示全部楼层 |阅读模式
<
本帖最后由 zhanzr21 于 2022-8-17 19:03 编辑

#申请原创#
上一篇文章中讲到DSP作为LKS32AT085的外设,  这个DSP还可以独立运行作为协处理器工作. 它与LKS32AT085的主核心CortexM0的区别如下:
1. 需要Cortex M0初始化代码和数据, 无法自动从Flash启动
2. 本身无中断, 可以引起Cortex M0的中断
3. 无Stack概念, 即DSP上运行的代码不能调用函数.
除此之外, 这个DSP属于凌欧的自主指令集, 目前是没有高级语言编译器的, 只有一个汇编器+模拟器的工具. 目前看来在上面开发程序还是比较费人工的, 希望厂家继续提高此处的开发者体验.

DSP程序运行基本模式
simple_dsp_standalone_process.png
首先DSP中的代码不能自动启动,  需要Cortex M0初始化Code和data段. 一旦运行起来, Cortex M0即可以去做其他工作. 等DSP上的代码运行完了,  可以通过指令发起Cortex M0的外设中断, Cortex M0可以来取数据以及初始化下一次的运算.

这里以一个小例子来看看基本的DSP代码开发与使用: arctan和直角三角形求斜边长度的运算
DSP有一个数学函数, 输入直角三角形的两边(X,Y), 可以求取夹角以及斜边长度.
arctan_mode_triangle.png
DSP作为外设
代码如下:

  1. typedef struct str_arctan_result {
  2.   uint16_t arctan;
  3.   uint16_t mod;
  4. } arctan_result;

  5. typedef struct str_arctan_input {
  6.   uint16_t x;
  7.   uint16_t y;
  8. } arctan_input;

  9. arctan_result cpu_issue_arctan_mod(arctan_input input) {
  10.   DSP_SC &= (~BIT2);
  11.   DSP_CORDIC_X = input.x;
  12.   DSP_CORDIC_Y = input.y;

  13.   arctan_result res;
  14.   res.arctan = DSP_CORDIC_ARCTAN;
  15.   res.mod = DSP_CORDIC_MOD;

  16.   return res;
  17. }
验证一下结果:
  1. DSP as a periph delta:0
  2. 2AAB, 2002
角度: 0x2AAB/0x7FFF = 0.33335367900631735 大约是π/3, 也就是60度.
斜边长: 0x2002 约等于0x1000的两倍. 可以看出是个30度,60度的直角三角形.

DSP单独运行

首先要写DSP上运行的代码
  1.     LDRDHI  R3 R4 0x0
  2.     ARCTAN  R5 R3 R4

  3.         # insert dummy inst to wait for arctan finish
  4.         ADD     R0 R0 R0
  5.     ADD     R0 R0 R0
  6.     ADD     R0 R0 R0
  7.         ADD     R0 R0 R0
  8.     ADD     R0 R0 R0
  9.     ADD     R0 R0 R0
  10.         ADD     R0 R0 R0
  11.     ADD     R0 R0 R0
  12.     ADD     R0 R0 R0
  13.     ADD     R0 R0 R0
  14.     ADD     R0 R0 R0
  15.     ADD     R0 R0 R0
  16.     ADD     R0 R0 R0
  17.     ADD     R0 R0 R0
  18.     ADD     R0 R0 R0
  19.         # arctan is stored at 0x5 in dsp's data mem
  20.         STRWI   R5 0x5
  21.         # module is stored at 0x6 in dsp's data mem        
  22.         STRWI        R6 0x6
  23.     IRQ

  24.     ADD     R0 R0 R0
  25.     ADD     R0 R0 R0
  26.     ADD     R0 R0 R0
  27.     ADD     R0 R0 R0
将以上代码保存为arctan_simple.code, 其中arctan_simple为工程名
再准备一个DSP的数据文件, 保存为arctan_simple.data, 内容如下:
  1. 0x10001BB6
  2.         0x00000000
其中0x10001BB6即为要运算的X,Y值. 0x00000000为对齐值, 实际使用中如果发现不补齐, 运算出问题. 原因文档中没有找到.
将上述两个文件放在模拟器相同的目录, 修改工程配置文件:
  1. prj: arctan_simple
再运行模拟器(此处模拟器其实是模拟器+汇编器二合一).
  1. $ ./LKS081DSP_Emulator.exe
  2. LKS081 DSP Emulator v1.1
  3. Released on 2020-3-9
  4. Author: zhangwl@linkosemi.com
  5. Copyright. 2020 LINKO Semiconductor Co.,Ltd. All Rights Reserved.
  6. Current project is <arctan_simple>.
  7. Reading in <arctan_simple.code>...
  8. <arctan_simple.code> contains 24 asm instructions
  9. Reading in <arctan_simple.data>...
  10. <arctan_simple.data> contains 2 words

  11. 2022-08-17 11:38:53
  12. <arctan_simple> Emulation is starting ...
  13. Info: at Line 24: IRQ
  14. IRQ generated and DSP halted when PC = 19.
  15. <arctan_simple> Emulation Finished
  16. 3132us elapsed on Emulator.
  17. 24Cycles elapsed on DSP.

  18. Final GPR snapshot is as below:
  19. PC = 0x0000
  20. R0 = 0x00000000
  21. R1 = 0x00000000
  22. R2 = 0x00000000
  23. R3 = 0x00001000
  24. R4 = 0x00001bb6
  25. R5 = 0x00002aa0
  26. R6 = 0x00001ff0
  27. R7 = 0x00000000
  28. 请按任意键继续. . .
以上操作等于 汇编+模拟. 在同级目录下面可以看到output目录, 里面有模拟的日志和汇编出来的二进制代码.
二进制代码和上述.data文件拷贝到MCU的工程中, 就可以对DSP做初始化了.
Note: 对于同样的输入, 模拟器运行的结果与DSP作为外设时不一致.
0x2AAB vs 0x2AA0
0x2002 vs 0x1FF0
貌似误差很小, 其实是需要凌鸥的工程师重点看看, 误差从何而来.

打开output目录中arctan_simple.hex
  1. 0x0000f01c,
  2. 0x0000792b,
  3. 0x00000000,
  4. 0x00000000,
  5. 0x00000000,
  6. 0x00000000,
  7. 0x00000000,
  8. 0x00000000,
  9. 0x00000000,
  10. 0x00000000,
  11. 0x00000000,
  12. 0x00000000,
  13. 0x00000000,
  14. 0x00000000,
  15. 0x00000000,
  16. 0x00000000,
  17. 0x00000000,
  18. 0x0000b145,
  19. 0x0000b186,
  20. 0x0000e000,
  21. 0x00000000,
  22. 0x00000000,
  23. 0x00000000,
  24. 0x00000000,
这就是DSP要运行的二进制代码, 拷贝到MCU工程中去, 使之成为一个const的数组.
  1. const uint32_t test_code_arctan_simple[] = {
  2. 0x0000f01c,
  3. 0x0000792b,
  4. 0x00000000,
  5. 0x00000000,
  6. 0x00000000,
  7. 0x00000000,
  8. 0x00000000,
  9. 0x00000000,
  10. 0x00000000,
  11. 0x00000000,
  12. 0x00000000,
  13. 0x00000000,
  14. 0x00000000,
  15. 0x00000000,
  16. 0x00000000,
  17. 0x00000000,
  18. 0x00000000,
  19. 0x0000b145,
  20. 0x0000b186,
  21. 0x0000e000,
  22. 0x00000000,
  23. 0x00000000,
  24. 0x00000000,
  25. 0x00000000,
  26. };
另外上文的.data文件也需要类似处理:
  1. const uint32_t test_data_arctan_simple[] = {
  2. 0x10001BB6,
  3. 0x00000000,
  4. };
这一点实在想吐槽, 为啥生成代码时不能自动生成C语言的数组呢, 希望凌鸥的工程师能发发力, 把细节做好一点.
以下是MCU中初始化DSP的代码与数据的代码样例, 为简便没有使能DSP的中断, 使用了不断poll标志位的方式.
  1. arctan_result dsp_issue_arctan_mod_poll(const uint32_t *code_ptr,
  2.                                         const uint16_t code_u32_len,
  3.                                         const uint32_t *data_ptr,
  4.                                         const uint8_t data_u32_len) {
  5.   volatile uint16_t arctan, mod;
  6.   uint32_t i;

  7.   // dsp data mem flush
  8.   for (i = 0; i < 64; i++) {
  9.     REG32(DSP_DATA_MEM_BASE + i * 4) = 0;
  10.   }

  11.   // dsp code mem flush
  12.   for (i = 0; i < 512; i++) {
  13.     REG32(DSP_CODE_MEM_BASE + i * 4) = 0;
  14.   }

  15.   // dsp data mem init
  16.   for (i = 0; i < data_u32_len; i++) {
  17.     REG32(DSP_DATA_MEM_BASE + i * 4) = data_ptr[i];
  18.   }

  19.   // dsp code mem init
  20.   // code length 200 half word
  21.   for (i = 0; i < code_u32_len; i++) {
  22.     REG32(DSP_CODE_MEM_BASE + i * 4) = code_ptr[i];
  23.   }

  24.         // Pause DSP
  25.         DSP_SC |= BIT1;
  26.         // Reset DSP PC
  27.         DSP_SC |= BIT2;
  28.         // Clear the IRQ flag
  29.         DSP_SC |= BIT0;

  30.         // Start DSP
  31.         DSP_SC = BIT0;
  32.         
  33.         // wait until irq set and dsp paused
  34.         while ((BIT0) != (DSP_SC & (BIT0))) {
  35.       __WFI();
  36.         }
  37.         
  38.   arctan_result res;
  39.   res.arctan = REG32(DSP_DATA_MEM_BASE + 5 * 4);
  40.   res.mod = REG32(DSP_DATA_MEM_BASE + 6 * 4);
  41.   return res;
  42. }
来看看结果:
  1. DSP standalone delta:1
  2. 2AAC, 2002
Note: 对于同样的输入, 模拟器运行的结果/DSP作为外设/DSP单独运行全部不一致.
0x2AAB        vs                0x2AA0                  vs               0x2AAC
0x2002         vs                0x1FF0                  vs               0x2002
貌似误差很小, 但作者实在想知道究竟是哪个地方不精确呢.

希望官方工程师能注意到这些误差, 后面能做相应的更正.

DSP指令一览
如上所述, 这个DSP没有Stack的概念, 导致不能调用函数, 这个不算bug, 因为本身设计目标不是一个完整的内核, 而是辅助数**算的协处理器.
这里把它的指令集和与Cortex M0的指令集放在一起做一个简短的对比.
Cortex M0指令集DSP指令集
整数运算ADCSADD
ADDADDI
ANDSSUB
ASRSASR
CMNASRI
CMPLSL
EORSLSLI
LSLSMAC
LSRSMACI
MULSDIV
ORRSSAT
REVSATI
REV16
REVSH
RORS
RSBS
SBCS
SUB
SXTB
SXTH
TST
BICS
UXTB
UXTH
三角函数SIN_COS
ARCTAN
其他函数SQRT
数据存取ADRLDRWI
LDMLDRDHI
LDRSTRWI
LDRB
LDRHSTRDHI
LDRSB
LDRSH
MOV
MRS
MSR
PUSH
POP
STM
STR
STRB
STRH
分支跳转BJUMP
BXJUMPI
JLE
JLEI
控制BKPTIRQ
WFINOP
WFE
CPSID
CPSIE
DMB
DSB
ISB
MVNS
NOP
SEV
SVC
总体而言, 这个DSP内核缺乏Stack相关指令, 缺乏条件判断指令, 缺乏中断相关指令, 比起Cortex M0, 多了一些数学函数, 多了除法指令. 这也是符合本身的定位的.

本文完整的测试代码下载地址点这里.





明天真的好 发表于 2022-8-23 09:10 | 显示全部楼层
这个做的很不错了,感谢楼主的分享。
kiwis66 发表于 2022-8-23 20:51 | 显示全部楼层
那俩图,想表达什么
鸥芯电驱港港 发表于 2022-10-11 20:59 | 显示全部楼层
感谢楼主的分享,这篇DSP测评全是干货。
 楼主| zhanzr21 发表于 2022-10-12 21:53 | 显示全部楼层
如果有机会, 我想跟官方的工程师交流下, 关于模拟器/硬件DSP 计算结果目前有些不一致, 虽然不算大问题, 想搞清楚原因
上下而求索 发表于 2022-10-13 08:50 | 显示全部楼层
zhanzr21 发表于 2022-10-12 21:53
如果有机会, 我想跟官方的工程师交流下, 关于模拟器/硬件DSP 计算结果目前有些不一致, 虽然不算大问题, 想 ...

这个可以的,zhaojie@linkosemi.com,可以把联系方式发邮箱里。
laocuo1142 发表于 2022-10-13 16:19 来自手机 | 显示全部楼层
这是一篇受官方认可的测评贴啊,点赞支持

评论

互相学习  发表于 2022-10-13 20:56
lcr12 发表于 2022-10-17 16:07 | 显示全部楼层
lks08系列带dsp核,可以计算电机相关的参数,而电网的相关参数跟三相资粮电机的参数非常相似,既然能计算电机的数据,也可以用到电网上计算FFT实现谐波计算
大道知简行不简 发表于 2022-12-19 00:18 | 显示全部楼层
这么测试DSP, 还是没有发挥出应有的性能,例程太简单,远不如直接用官方的Clark park PID纯DSP独立运行例程测试来的直接。可能维护论坛的原厂工程师对DSP也不大熟悉吧。评测第一名,有点水。。。@zhanzr21 @鸥芯电驱港港 @上下而求索
 楼主| zhanzr21 发表于 2022-12-19 10:58 | 显示全部楼层
本帖最后由 zhanzr21 于 2022-12-19 11:19 编辑
大道知简行不简 发表于 2022-12-19 00:18
这么测试DSP, 还是没有发挥出应有的性能,例程太简单,远不如直接用官方的Clark park PID纯DSP独立运行例程 ...

谢谢指点,这个确实是我学习凌鸥的硬件DSP的第一篇评测,理解还不深.
选简单的例子是为了说明硬件特性.
发评测贴主要希望分享交流.
Cheky 发表于 2022-12-19 23:14 | 显示全部楼层
大道知简行不简 发表于 2022-12-19 00:18
这么测试DSP, 还是没有发挥出应有的性能,例程太简单,远不如直接用官方的Clark park PID纯DSP独立运行例程 ...

官方的Clark park PID纯DSP独立运行例程哪里下载??
大道知简行不简 发表于 2023-1-13 12:05 | 显示全部楼层
Cheky 发表于 2022-12-19 23:14
官方的Clark park PID纯DSP独立运行例程哪里下载??

发个官方的参考DSP代码

foc_app.rar

2.23 KB, 下载次数: 11

您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1017

帖子

34

粉丝
快速回复 在线客服 返回列表 返回顶部