社区导航

 

搜索
查看: 964|回复: 9

[原创] 【旧帖浮沉3】你想指定变量地址?其实他需要的是一个共享内存机制

[复制链接]

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

发表于 2018-9-6 22:13 | 显示全部楼层 |阅读模式
照例,翻老帖子 ——这里,一次性和这些老帖子的作者道个歉:为了方便我的记忆,我在每个老帖子的标题前加了一些字样
分别是 CHECKED MARKED LEFT
CHECKED表示我已经看过;
MARKED表示我已经对这个老帖子进行过挖掘,也就是现在我干的事情。
LEFT 表示我过后会MARKED,但今天我先标记留着。

任何一个帖子,不管如何,作者都应该得到尊重,但这些帖子基本都是超过10年以上,而且作者和那些回答的热心楼主可能早已经不在。
我会尽快想到一种新的规整办法,避免再用这样的方式 冒犯各位。

好了,说回主题。
这次说的是这个帖子。

[url=【MARKED】C语言中定义全局变量时,如何在定义变量时就指定好变量的地址 http://bbs.eeworld.com.cn/forum. ... 7922&fromuid=115166 (出处: 电子工程世界-论坛)]C语言中定义全局变量时,如何在定义变量时就指定好变量的地址[/url]


此内容由EEWORLD论坛网友辛昕原创,如需转载或用于商业用途需征得作者同意并注明出处


来源:EEWorld 编程基础板块,转载请附上链接

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:18 | 显示全部楼层
首先,针对这个标题,这本身就是一个完整的问题。
我可以先简单回答一下
在“正常的C”里,这件事按道理是不可能的,因为变量的分配行为发生在编译时,发生在栈上面,只有堆的空间是可以有程序员自由掌控分配和回收的。
但即便如此,程序员仍然不能指定地址。

但是,在单片机里,一个我到现在还说不清楚的原因,见鬼,它可以。
虽然用到的方式,有一点让新手感到陌生,大抵就是形如下文:

(int *)0x0001023 .....

是的,我承认,当我看到这个题目的时候,我第一反应,就以为他是在问这个问题。
甚至我们看完主题楼里,楼主的描述,我们都会这样认为。

还好,楼主的话语虽然不算多,大概100字不到的样子,很快他就提到了这么做的 最初原因
小弟现在写一个单片机的程序,由于项目比较紧,就分给两个人做,小弟不懂汇编,要用C写程序,另一个汇编很强,但是不懂C语言,我们现在的想法是二个人一起写程序,最后和到一起运行,其中数据的交互想通过公用数据空间来实现

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

394

TA的帖子

8

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2018-9-6 22:24 | 显示全部楼层
能写出这样的程序来,对硬件,内存空间分配一定很熟悉的。否则很容易就绕在其中了

点评

这个其实不难,单片机程序写多了,都会遇到这个问题。 搜一下百度就能明白。 至于C,它的底子,其实还就真的是 地址和内存 这两个关键词。  详情 回复 发表于 2018-9-6 22:34

回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:26 | 显示全部楼层
本帖最后由 辛昕 于 2018-9-6 22:33 编辑

我先不提这个问题本身的答案,尽管我没有很认真地看下面的回答。
但是对这个问题本身,因为对我来说,它已经不是问题,甚至不需要去做什么 指定地址。
所以,我的思维很快转向了另一个问题。

关于提问和沟通的问题。

其实在生活中,我们的确经常发生这种事情——我们说出口的那个问题,其实和我们真正面对的问题,往往不是同一个问题。

我们对一个自己面对的实际问题,经过一阵子的思考和初步尝试后,假如解决不了。
我们多少会对这个问题得到自己的初步解决方向。

比方,楼主,他因为受到汇编的影响
——我几乎可以猜测,楼主当时,在C语言方面的理解能力,远远比不上他对汇编的熟悉程度。

因为对这个问题来说,像我这样常年写C,已经完全习惯用C的思维方式的人来说,马上就会联想到,内存的地址分配在哪里根本不重要,重要的是,我们可以通过引用变量名(更确切地说,更广泛地角度,我更喜欢用标识符 来表达这个概念)
直接得到它的地址(作为左值的时候),或者它位于的内存块(作为右值的时候)

我当年学习51,的确也曾学过,并且很熟练汇编,作为一个学生,我写过3000行代码的汇编程序。
但是因为使用汇编的时间相对而言极其短暂,我甚至已经忘记,在汇编里,没有变量这个概念,没有真正意义上的子函数。
在汇编里,其实所有东西,都只是 地址, 和地址指向的内容。
不管是函数,还是数组,还是内存空间,我们都通过 标识符记录那个地址值。
然后通过 基本汇编指令 对地址,对地址指向的内容 进行读写,仅此而已。

扯远了,说回来,就是,我其实十分理解楼主为什么会把
通过共享内存的方式 实现 数据耦合
理解成 需要在变量分配时就指定地址的问题。

但是——


八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:27 | 显示全部楼层
请注意,我是直到看到楼主后面的那段表述,我才慢慢思索到这一步。

我的第一反应,仍然是,告诉他,在单片机里,你可以通过 这样这样来实现。

而根本没想到,其实对于他的问题本身,这件事情本来就可以不做。

这也是导致了为什么在最初的楼层里,有人给出了和我类似的解答的原因。

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:34 | 显示全部楼层
lehuijie 发表于 2018-9-6 22:24
能写出这样的程序来,对硬件,内存空间分配一定很熟悉的。否则很容易就绕在其中了

这个其实不难,单片机程序写多了,都会遇到这个问题。
搜一下百度就能明白。

至于C,它的底子,其实还就真的是 地址和内存 这两个关键词。

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:38 | 显示全部楼层
直到第5楼,我才看到一个类似我所发现的答案:
如果是多线程或多CPU,可以这样做。
如果是单CPU,单线程,那么最好是C做主程序,汇编写模块,遵循C的调用规范进行调用,数据的传递用参数实现。


但这个人的回答的确比我第一反应的要更加完整,尽快简单的单片机程序,实际上很少遇到多线程的情况
——当然了,很少有人注意到,在最基本的单片机裸机程序里,哪怕就是只有一个最基础的 timer中断,实际上,此时这个程序已经是一个 两线程代码。

而后,在这个回答的启发下,作者继续进一步描述了他面对的环境

谢谢大家的帮忙,小弟感激不尽!
现在我的想法是主程序我写,然后我同事主要写一些中断,在同一个MCU上运行,单片机用的是MSP430,当有中断发生时,
触发同事写的中断程序,中断程序处理完以后,中断中处理好的数据就放在一块存储区域,然后我在主程序中去取那块存储
区域中的数据,然后执行响应的操作。其中还有一些比如液晶要显示的工作,也打算这样做,比如,要显示什么样的数据,
我先在存储区域中写进去数据,然后调用同事写的汇编程序,同事的汇编程序在那块指定的区域中取出数据,然后在液晶上
显示,用这种方法做怎样?有没有什么要注意的地方?还有,选择的那块公用的存储区域放在什么地方好那?会不会在程序
运行的过程中由于堆栈的分配把我的公用存储区域给破坏了?望高手帮忙啊

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:44 | 显示全部楼层
首先,对于5L的回答 ,我认为基本无可挑剔。
没什么可说的。

那么,对于楼主的进一步补充呢。
其实,他的问题并没什么特别,唯一要注意的地方就是
如果,显示屏刷新的频率选择的不恰当,那么很可能你看到的数据不是最新的数据。

这个解决起来其实不难。
那就是,你可以在数据更新时再刷新显示。
现在的单片机很快,何况这是16位MSP430,我想速度完全没问题。

而且,除非你的LCD驱动放在中断里处理——假如是这样,我想大概是没必要的。

总之,我认为,在这个问题时,直接调用共享的数据去就可以了。

如果想要处理的更简单一些——
就是说,甚至不需要 直接用这个公共数据区做两个模块之间的耦合,那么可以更加简单。
就是把显示刷新的代码,做成一个函数调用 ,作为一个回调函数,每一次公共数据区的数据更新时或者其他策略 (比如定时策略),直接就调用一次刷新,事情就完了。

——事实上我觉得 因为我的猜测,我很可能把问题复杂化了。
但即便如此,我的意思是,我仍然没有遇到任何困难,根本不需要什么指定地址。

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:50 | 显示全部楼层
最后说的话

首先,我认为这种“说出的问题其实不是根本问题”是非常常见的。
很多时候,销售和客户之间也经常这样。

因为人有时候 并不真正理解,或者没办法真正确切表达出自己的想法。
或者更夸张的说——是因为,人没办法用倾听者能正确理解的 语言 ,来表达自己的方式。

这个时候,我们要做的不是那些鸡汤文里教你的,这个那个,那个这个,更不需要你提高自己的演说能力,理解能力。

其实,我们需要做的,就是耐心。

比方说楼主,其实他在主题楼里,尽管他起了一个不好的标题,但他简短的进一步补充,已经充分表现了他面对的真正问题。
这非常好。

另外就是,看这个帖子的人,需要耐心。
坦白说,在我远离板块,不再发帖子的时间里,我变得对简单问题没有耐心,对说的乱七八糟的问题没有耐心。
对于没能给自己带来名声,带来金钱利益的问题没有耐心......

更早一些时候,其实,很多时候我都没有真正理解问题,很可能第一眼看到标题,就先入为主。
我并没有任何不敬的意思,但我认为,沙发板凳帖子里的那两位兄弟,其实也是这样。

主题楼里的说明,其实足够暴露了问题,任何一个有经验的单片机C程序员,都能给出和5L一样的回答。
包括我自己,今天的我,面对这个老问题,风轻云淡的,在洗完澡,洗完衣服,等着休息,随心所欲对一个帖子指点的时候——
我仍然在第一反应,忽略了主题楼的描述。

所以,一定要有耐心。
不仅问的人要有耐心,听的人也要有耐心
然后才是技巧和聪明才智。

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

7870

TA的帖子

54

TA的资源

裸片初长成(中级)

Rank: 11Rank: 11Rank: 11Rank: 11

荣誉会员勋章

 楼主| 发表于 2018-9-6 22:51 | 显示全部楼层
我,似乎在苛责这些距今时光久远的帖子,其实,我是在勉励自己。

原本,我对于这项活动,更多地当成一种任务,因为这些问题,要么我不了解具体的背景无法回答。
要么对于今天的我来说,基本99%都不再是问题。

但是,写到第三篇,我发现自己收获了很多,在技术之外的东西。

八年一梦,洗尽铅华,重头再来


回复

使用道具 举报

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

关闭

站长推荐上一条 /6 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-10-15 07:19 , Processed in 0.292974 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表