通过GPIO形式的Hardware token来解决版本管理问题

本文探讨了在嵌入式软件开发中,如何通过GPIO硬件token在不增加维护成本的前提下,根据不同用户需求定制软件功能。通过SMT阶段的电阻选择,形成硬件标识,程序据此判断执行相应版本的功能。

在嵌入式软件开发中,有这么一种情况,同一个硬件版本,要给用户A和用户B供货,两用户对产品的功能或行为要求是不同的。

正常情况,就是给用户A一版软件,给用户B另外一版软件。

这样做就增加了维护、发布和部署的成本,如果这样定制型的用户需求很多的话,就会为软件配置管理带来极大的不便。

能不能用户A和B公用一份软件,还能实现功能上的区分?

所有的问题,都有答案。

这个问题也有解决方法:可以在硬件上预留几个GPIO,用来做hardware token,在机器上电时,软件读取GPIO状态,来区分不同的产品版本,来执行不同的功能。

上面的一排电阻,在SMT时,每一个都可以选择贴或者不贴,这样就能组合出不同的hardware token信息,每一个GPIO就是1个bit。

在具体使用时,先将GPIO内部拉高,并设置为输入。在芯片的Reference Manual(IMX6ULLRM.pdf)里,在IOMUX Controller章节里,有关于上下拉的设置:

 

我们看到这个芯片手册里关于端子的设置,pull up是有三种上拉电阻,47K、100K、22K。

在我们外部电路中,下拉电阻是4.7K Ohm。

一般芯片的IO口电压使用3.3V(也有使用1.8V情况)。

如果不贴外部下拉电阻,则读取电平为高电平,和上拉电压一样,为3.3V。

Rebuild started: Project: empty_LP_MSPM0G3507_nortos_keil *** Using Compiler 'V6.21', folder: 'D:\左猪崽\ARM\ARMCLANG\Bin' Rebuild target 'empty_LP_MSPM0G3507_nortos_keil' Note: source file '.\Car.c' - object file renamed from '.\Objects\Car.o' to '.\Objects\car_1.o'. Note: source file '.\BEEP.c' - object file renamed from '.\Objects\BEEP.o' to '.\Objects\beep_1.o'. Note: source file '.\Track.c' - object file renamed from '.\Objects\Track.o' to '.\Objects\track_1.o'. Note: source file '.\KEY.c' - object file renamed from '.\Objects\KEY.o' to '.\Objects\key_1.o'. Before Build - User command #1: cmd.exe /C "E:\TI\OLED2\OLED\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\../../../../../../tools/keil/syscfg.bat 'E:\TI\OLED2\OLED\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\' empty.syscfg" Using Sysconfig Tool from "E:\TI\sysconfig_cli.bat.bat" "Update the file located at <sdk path>/tools/keil/syscfg.bat to use a different version" Running script... Validating... info: /ti/project_config/ProjectConfig deviceSpin: Note: User must select a device after migration. Generating Code (empty.syscfg)... Writing E:\TI\OLED2\OLED\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.c... Unchanged E:\TI\OLED2\OLED\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.h... Unchanged E:\TI\OLED2\OLED\examples\nortos\LP_MSPM0G3507\driverlib\empty\Event.dot... assembling startup_mspm0g350x_uvision.s... ../empty.c(34): error: 'BEEP.h' file not found 34 | #include "BEEP.h" | ^~~~~~~~ 1 error generated. compiling empty.c... compiling delay.c... compiling ti_msp_dl_config.c... compiling board.c... BEEP.c(1): warning: In file included from... ./BEEP.h(1): warning: extra tokens at end of #ifndef directive [-Wextra-tokens] 1 | #ifndef BEEP.h | ^ | // ./BEEP.h(2): warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions] 2 | #define BEEP.h | ^ BEEP.c(19): error: expected identifier or '(' 19 | void BEEP(int delay, int en){ | ^ ./BEEP.h(2): note: expanded from macro 'BEEP' BEEP.c(40): error: use of undeclared identifier 'DL_GPIO_PORT_A' 40 | DL_GPIO_togglePins(BEEP_GPIO, BEEP_GPIO_PIN);// 缈昏浆鐢靛钩 | ^ ./BEEP.h(4): note: expanded from macro 'BEEP_GPIO' 4 | #define BEEP_GPIO DL_GPIO_PORT_A // 浣跨敤TI椹卞姩搴撶殑瀹? | ^ BEEP.c(41): error: use of undeclared identifier 'DL_GPIO_PORT_A' 41 | DL_GPIO_togglePins(BEEP_GPIO, BEEP_LED_PIN);// 缈昏浆鐢靛钩 | ^ ./BEEP.h(4): note: expanded from macro 'BEEP_GPIO' 4 | #define BEEP_GPIO DL_GPIO_PORT_A // 浣跨敤TI椹卞姩搴撶殑瀹? | ^ BEEP.c(49): error: use of undeclared identifier 'DL_GPIO_PORT_A' 49 | DL_GPIO_setPins(BEEP_GPIO, BEEP_GPIO_PIN); | ^ ./BEEP.h(4): note: expanded from macro 'BEEP_GPIO' 4 | #define BEEP_GPIO DL_GPIO_PORT_A // 浣跨敤TI椹卞姩搴撶殑瀹? | ^ BEEP.c(50): error: use of undeclared identifier 'DL_GPIO_PORT_A' 50 | DL_GPIO_clearPins(BEEP_GPIO, BEEP_LED_PIN);//杈撳嚭浣庣數骞? | ^ ./BEEP.h(4): note: expanded from macro 'BEEP_GPIO' 4 | #define BEEP_GPIO DL_GPIO_PORT_A // 浣跨敤TI椹卞姩搴撶殑瀹? | ^ 2 warnings and 5 errors generated. compiling BEEP.c... Car.c(1): warning: extra tokens at end of #include directive [-Wextra-tokens] 1 | #include "Car.h".h" | ^ | // Car.c(1): warning: missing terminating '"' character [-Winvalid-pp-token] 1 | #include "Car.h".h" | ^ 2 warnings generated. compiling Car.c... Track.c(27): error: use of undeclared identifier 'Track_GPIO' 27 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_1) > 0 ) | ^ Track.c(27): error: use of undeclared identifier 'Track_PIN_1' 27 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_1) > 0 ) | ^ Track.c(29): error: use of undeclared identifier 'H' 29 | track[i] = H; //淇濈暀涓洪珮鐢靛钩 | ^ Track.c(34): error: use of undeclared identifier 'L' 34 | track[i] = L;//淇濈暀涓轰綆鐢靛钩 | ^ Track.c(38): error: use of undeclared identifier 'Track_GPIO' 38 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_2) > 0 ) | ^ Track.c(38): error: use of undeclared identifier 'Track_PIN_2' 38 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_2) > 0 ) | ^ Track.c(40): error: use of undeclared identifier 'H' 40 | track[i] = H; //淇濈暀涓洪珮鐢靛钩 | ^ Track.c(45): error: use of undeclared identifier 'L' 45 | track[i] = L;//淇濈暀涓轰綆鐢靛钩 | ^ Track.c(50): error: use of undeclared identifier 'Track_GPIO' 50 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_3) > 0 ) | ^ Track.c(50): error: use of undeclared identifier 'Track_PIN_3' 50 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_3) > 0 ) | ^ Track.c(52): error: use of undeclared identifier 'H' 52 | track[i] = H; //淇濈暀涓洪珮鐢靛钩 | ^ Track.c(57): error: use of undeclared identifier 'L' 57 | track[i] = L;//淇濈暀涓轰綆鐢靛钩 | ^ Track.c(61): error: use of undeclared identifier 'Track_GPIO' 61 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_4) > 0 ) | ^ Track.c(61): error: use of undeclared identifier 'Track_PIN_4' 61 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_4) > 0 ) | ^ Track.c(63): error: use of undeclared identifier 'H' 63 | track[i] = H; //淇濈暀涓洪珮鐢靛钩 | ^ Track.c(68): error: use of undeclared identifier 'L' 68 | track[i] = L;//淇濈暀涓轰綆鐢靛钩 | ^ Track.c(73): error: use of undeclared identifier 'Track_GPIO' 73 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_5) > 0 ) | ^ Track.c(73): error: use of undeclared identifier 'Track_PIN_5' 73 | if( DL_GPIO_readPins(Track_GPIO, Track_PIN_5) > 0 ) | ^ Track.c(75): error: use of undeclared identifier 'H' 75 | track[i] = H; //淇濈暀涓洪珮鐢靛钩 | ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. compiling Track.c... compiling oled.c... KEY.c(26): error: use of undeclared identifier 'KEY_GPIO' 26 | if( DL_GPIO_readPins(KEY_GPIO, KEY1) > 0 ) | ^ KEY.c(26): error: use of undeclared identifier 'KEY1' 26 | if( DL_GPIO_readPins(KEY_GPIO, KEY1) > 0 ) | ^ KEY.c(33): error: use of undeclared identifier 'KEY_GPIO' 33 | if( DL_GPIO_readPins(KEY_GPIO, KEY1) > 0 ) | ^ KEY.c(33): error: use of undeclared identifier 'KEY1' 33 | if( DL_GPIO_readPins(KEY_GPIO, KEY1) > 0 ) | ^ KEY.c(41): error: use of undeclared identifier 'KEY_GPIO' 41 | if( DL_GPIO_readPins(KEY_GPIO, KEY2) > 0 ) | ^ KEY.c(41): error: use of undeclared identifier 'KEY2' 41 | if( DL_GPIO_readPins(KEY_GPIO, KEY2) > 0 ) | ^ KEY.c(48): error: use of undeclared identifier 'KEY_GPIO' 48 | if( DL_GPIO_readPins(KEY_GPIO, KEY2) > 0 ) | ^ KEY.c(48): error: use of undeclared identifier 'KEY2' 48 | if( DL_GPIO_readPins(KEY_GPIO, KEY2) > 0 ) | ^ KEY.c(58): error: use of undeclared identifier 'KEY_GPIO' 58 | if( DL_GPIO_readPins(KEY_GPIO, KEY3) > 0 ) | ^ KEY.c(58): error: use of undeclared identifier 'KEY3' 58 | if( DL_GPIO_readPins(KEY_GPIO, KEY3) > 0 ) | ^ KEY.c(65): error: use of undeclared identifier 'KEY_GPIO' 65 | if( DL_GPIO_readPins(KEY_GPIO, KEY3) > 0 ) | ^ KEY.c(65): error: use of undeclared identifier 'KEY3' 65 | if( DL_GPIO_readPins(KEY_GPIO, KEY3) > 0 ) | ^ KEY.c(75): error: use of undeclared identifier 'KEY_GPIO' 75 | if( DL_GPIO_readPins(KEY_GPIO, KEY4) > 0 ) | ^ KEY.c(75): error: use of undeclared identifier 'KEY4' 75 | if( DL_GPIO_readPins(KEY_GPIO, KEY4) > 0 ) | ^ KEY.c(82): error: use of undeclared identifier 'KEY_GPIO' 82 | if( DL_GPIO_readPins(KEY_GPIO, KEY4) > 0 ) | ^ KEY.c(82): error: use of undeclared identifier 'KEY4' 82 | if( DL_GPIO_readPins(KEY_GPIO, KEY4) > 0 ) | ^ KEY.c(92): error: use of undeclared identifier 'KEY_GPIO' 92 | if( DL_GPIO_readPins(KEY_GPIO, KEY5) > 0 ) | ^ KEY.c(92): error: use of undeclared identifier 'KEY5' 92 | if( DL_GPIO_readPins(KEY_GPIO, KEY5) > 0 ) | ^ KEY.c(99): error: use of undeclared identifier 'KEY_GPIO' 99 | if( DL_GPIO_readPins(KEY_GPIO, KEY5) > 0 ) | ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. compiling KEY.c... ".\Objects\empty_LP_MSPM0G3507_nortos_keil.axf" - 44 Error(s), 4 Warning(s). Target not created. Build Time Elapsed: 00:00:03
最新发布
07-22
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜流冰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值