We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
因为工作的需要用到了TI 的C2000系列DSP(TMS320F28377D),本以为移植shell是简单的事情,实际移植起来发现挺多的问题,在这里分享处理,希望能帮助到其他有类似需求的朋友,也希望作者能改进过来
编译器配置 : CCS12.0 使用eabi模式
shellCommand : { _shell_command_start = .; *(shellCommand) _shell_command_end = .; } > FLASHA_M //flash的位置根据实际情况来确定
然后在代码中修改和编译器相关的内容
#ifndef SHELL_SECTION #if defined(__CC_ARM) || defined(__CLANG_ARM) #define SHELL_SECTION(x) __attribute__((used,section(x))) #elif defined (__IAR_SYSTEMS_ICC__) #define SHELL_SECTION(x) @ x #elif defined(__GNUC__) || defined(__TI_EABI__) #define SHELL_SECTION(x) __attribute__((section(x))) #else #define SHELL_SECTION(x) #endif #endif #ifndef SHELL_USED #if defined(__CC_ARM) || defined(__CLANG_ARM) #define SHELL_USED __attribute__((used)) #elif defined (__IAR_SYSTEMS_ICC__) #define SHELL_USED __root #elif defined(__GNUC__) #define SHELL_USED __attribute__((used)) #elif defined(__TI_EABI__) #define SHELL_USED __attribute__((retain)) #else #define SHELL_USED #endif #endif
void shellInit(Shell *shell, char *buffer, unsigned short size) { shell->parser.length = 0; shell->parser.cursor = 0; shell->info.user = NULL; shell->status.isChecked = 1; shell->parser.buffer = buffer; shell->parser.bufferSize = size / (SHELL_HISTORY_MAX_NUMBER + 1); #if SHELL_HISTORY_MAX_NUMBER > 0 shell->history.offset = 0; shell->history.number = 0; shell->history.record = 0; for (short i = 0; i < SHELL_HISTORY_MAX_NUMBER; i++) { shell->history.item[i] = buffer + shell->parser.bufferSize * (i + 1); } #endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ #if SHELL_USING_CMD_EXPORT == 1 #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000) shell->commandList.base = (ShellCommand *)(&shellCommand$$Base); shell->commandList.count = ((uint32_t)(&shellCommand$$Limit) - (uint32_t)(&shellCommand$$Base)) / sizeof(ShellCommand); #elif defined(__ICCARM__) || defined(__ICCRX__) shell->commandList.base = (ShellCommand *)(__section_begin("shellCommand")); shell->commandList.count = ((uint32_t)(__section_end("shellCommand")) - (uint32_t)(__section_begin("shellCommand"))) / sizeof(ShellCommand); #elif defined(__GNUC__) || defined(__TI_EABI__) shell->commandList.base = (ShellCommand *)(&_shell_command_start); shell->commandList.count = ((uint32_t)(&_shell_command_end) - (uint32_t)(&_shell_command_start)) / sizeof(ShellCommand); #else #error not supported compiler, please use command table mode #endif #else shell->commandList.base = (ShellCommand *)shellCommandList; shell->commandList.count = shellCommandCount; #endif shellAdd(shell); shellSetUser(shell, shellSeekCommand(shell, SHELL_DEFAULT_USER, shell->commandList.base, 0)); shellWritePrompt(shell, 1); }
处理数据类型差异
在DSP上char和int都是16位的,char的差异不影响程序,但是int的差异是影响的,所以需要把所有的int和 unsigned int 都修改为int32_t 或uint32_t,这里建议作者引用stdint.h等头文件,将类型都统一成和编译器无关的类型
处理代码的兼容性问题
TI的编译器不会根据使用情况自动做类型转换,比如你将uint16_t当成uint32_t来使用时,系统不会帮你做强制转换,从而导致代码的错误,这点希望作者能直接在源码中修正.下面列出移植过程中发现的代码问题:
void shellHandler(Shell *shell, char data) { SHELL_ASSERT(data, return); SHELL_LOCK(shell); #if SHELL_LOCK_TIMEOUT > 0 if (shell->info.user->data.user.password && strlen(shell->info.user->data.user.password) != 0 && SHELL_GET_TICK()) { if (SHELL_GET_TICK() - shell->info.activeTime > SHELL_LOCK_TIMEOUT) { shell->status.isChecked = 0; } } #endif /* 根据记录的按键键值计算当前字节在按键键值中的偏移 */ char keyByteOffset = 24; int32_t keyFilter = 0x00000000; //将int改成int32_t if ((shell->parser.keyValue & 0x0000FF00) != 0x00000000) { keyByteOffset = 0; keyFilter = 0xFFFFFF00; } else if ((shell->parser.keyValue & 0x00FF0000) != 0x00000000) { keyByteOffset = 8; keyFilter = 0xFFFF0000; } else if ((shell->parser.keyValue & 0xFF000000) != 0x00000000) { keyByteOffset = 16; keyFilter = 0xFF000000; } /* 遍历ShellCommand列表,尝试进行按键键值匹配 */ ShellCommand *base = (ShellCommand *)shell->commandList.base; for (short i = 0; i < shell->commandList.count; i++) { /* 判断是否是按键定义并验证权限 */ if (base[i].attr.attrs.type == SHELL_TYPE_KEY && shellCheckPermission(shell, &(base[i])) == 0) { /* 对输入的字节同按键键值进行匹配 */ if ((base[i].data.key.value & keyFilter) == shell->parser.keyValue && (base[i].data.key.value & (0xFFUL << keyByteOffset)) //将oxFF声明为32位 == ((uint32_t)data << keyByteOffset)) //将data强制转换为32位 { shell->parser.keyValue |= (uint32_t)data << keyByteOffset;//将data强制转换为32位 data = 0x00; if (keyByteOffset == 0 || (base[i].data.key.value & (0xFFUL << (keyByteOffset - 8)))== 0x00000000)//将oxFF声明为32位 { if (base[i].data.key.function) { base[i].data.key.function(shell); } shell->parser.keyValue = 0x00000000; break; } } } } if (data != 0x00) { shell->parser.keyValue = 0x00000000; shellNormalInput(shell, data); } if (SHELL_GET_TICK()) { shell->info.activeTime = SHELL_GET_TICK(); } SHELL_UNLOCK(shell); }
The text was updated successfully, but these errors were encountered:
感谢您的分享和指正
第一点:各个芯片的编译链都会有一些差异,没办法一次性全部覆盖,如果做了适配,可以提 PR 合入进来的
第二点:一开始做的时候确实是只考虑了 32 位的芯片,后面如果大改会整体处理一下
Sorry, something went wrong.
No branches or pull requests
因为工作的需要用到了TI 的C2000系列DSP(TMS320F28377D),本以为移植shell是简单的事情,实际移植起来发现挺多的问题,在这里分享处理,希望能帮助到其他有类似需求的朋友,也希望作者能改进过来
编译器配置 : CCS12.0 使用eabi模式
先要在链接文件CMD中增加shell的链接信息:
然后在代码中修改和编译器相关的内容
处理数据类型差异
在DSP上char和int都是16位的,char的差异不影响程序,但是int的差异是影响的,所以需要把所有的int和 unsigned int 都修改为int32_t 或uint32_t,这里建议作者引用stdint.h等头文件,将类型都统一成和编译器无关的类型
处理代码的兼容性问题
TI的编译器不会根据使用情况自动做类型转换,比如你将uint16_t当成uint32_t来使用时,系统不会帮你做强制转换,从而导致代码的错误,这点希望作者能直接在源码中修正.下面列出移植过程中发现的代码问题:
The text was updated successfully, but these errors were encountered: