12下一页

[经验] 【NanoPi2试用体验】-7 在 pi2上用裸机程序点亮LED的原理详细分析与实验

[复制链接]

技术员

发表于 2016-1-22 13:27:33   2610 查看 20 回复 显示全部楼层 倒序浏览
分享
感冒了!浑身乏力!郁闷死了!
先来点感想,我们老老实实写篇文章的过程,也是自己的重新思考的过程。查资料的过程也是个很好的学习过程,有些头脑里面似是而非的东西,会在这个过程中得到整理,强化。这样强化后的知识才能真正成为自己的知识。
所以管理员们催稿,不是在逼你,而是在督促你学习,进步!
反之,随随便便水一篇文章。力气是省了,拼拼凑凑就完事了。但是文章提交后,也就结束了,你大脑里还是一片空白,的知识点还是一团浆糊。
但是你想过没有,凑水文也要花时间的,时间花掉了。你学到东西了吗?
经常有人问:“我的时间去哪了?
其实,你自己才是偷走你时间的最大的贼。
总之,赔钱的买卖咱不干,还是老老实实写文章,学知识来得实在。
一、裸机程序运行准备工作
这次咱们就来看看裸机程序到底是怎样跑起来的。
从上次的文章我们可以看到,机器是如何引导起来的。
还记得上一篇文章里,我说的记住那些红色标记的地址了吗?
现在用到了那些标记过的地址了,我们再把这个图再借过来放这儿,方便查看。
parsing./android/partmap.txt:
part.0flash=mmc,0:2ndboot:     2nd:   0x200,0x8e00:                      :[RAW]
part.1 flash=mmc,0:bootloader:boot:   0x8000,0x77000:                    :[RAW]
part.2flash=mmc,0:boot:       fat:   0x100000,0x4000000:    boot.img   :[MBR] ./android/boot.img
part.3flash=mmc,0:system:     ext4:   0x4100000,0x2f200000:  system.img :[MBR] ./android/system.img
part.4flash=mmc,0:cache:      ext4:   0x33300000,0x1ac00000: cache.img   :[MBR] ./android/cache.img
part.5flash=mmc,0:misc:       emmc:   0x4e000000,0x800000:               :[MBR]
part.6flash=mmc,0:recovery:   emmc:   0x4e900000,0x1600000:              :[MBR]
part.7flash=mmc,0:userdata:   ext4:   0x50000000,0x0:       userdata.img :[MBR]./android/userdata.img
这次,我们还是借助于SD卡来引导我们的小pi2。
我们在这里要对SD卡来个“乾坤大挪移”,采取“偷梁换柱”的手法来实施我们的计划。      
那有人要问了:偷那个梁,换那个柱呢?
理论上,在友善官方提供的img中我们可以替换的地方有2个,一个是三星提供的2ndboot处,另外一个是友善提供的uboot处,替换掉这两个地方应该都能达到运行我们的裸机程序的目的。
个人猜测,cpu运行到这两个地方的后,现场的环境应该是不一样的,具体有哪些不同,要看这2个不同阶段的boot程序了。
这里面有一个问题要提前提醒你,那就是如果你的裸机程序要是替换2ndboot,那么你的裸机程序不能超过16k,否则,产生意想不到的后果。
原因如下:
下面再来看张图图吧!
老让你看图有点烦哈!没办法,我文字表达能力太差。还是看图说得明白
00.PNG
没看懂也没关系,只要记住一点,我们自己写的替换2ndboot的程序不能大于16k,
为什么,因为三星规定死了。
有较真的又要问了,我就要大于16k怎么办?
哎,愁人!办法也是有的,就是你要把自己写的程序分成2段,分别加载,当然所有的初始化要你自己做好。并且要你自己在的程序里,处理运行环境程序初始化(cpu、内存)、复制、转移等等工作。
现在该知道怎么偷天换日了吧。
对了,就使用我们的程序替换掉2ndboot,让internalrom把我们的程序当成2ndboot,调入到sram里执行,从而达到我们的程序运行的目的。
好了现在终于到了准备一段程序来练练手的时候了?
二、点亮led程序的原理及程序
我们的重点在于讲清楚程序运行的原理,而不是程序的复杂性。所以能简单就简单点,高大上的程序要靠您来完成了。
就拿“点灯大法”来练练手吧!
先说说点灯大法的原理,不知道有多少高手都是从这里走出来的。
我们这次就拿这种直径 3mm 插件led灯珠来说说点亮的原理吧!
01.PNG
首先,看看led的发光原理
LED(Light Emitting Diode),发光二极管,是一种能够将电能转化为可见光的固态的半导体器件,它可以直接把电转化为光。LED的心脏是一个半导体的晶片,晶片的一端附在一个支架上,一端是负极,另一端连接电源的正极,使整个晶片被环氧树脂封装起来。半导体晶片由两部分组成,一部分是P型半导体,在它里面空穴占主导地位,另一端是N型半导体,在这边主要是电子。但这两种半导体连接起来的时候,它们之间就形成一个P-N结。当电流通过导线作用于这个晶片的时候,电子就会被推向P区,在P区里电子跟空穴复合,然后就会以光子的形式发出能量,这就是LED灯发光的原理。而光的波长也就是光的颜色,是由形成P-N结的材料决定的。
看明白了吗?就是要给led通过电流。
借用我们的小pi2的user led说明一下:
02.PNG
那怎么通过电流?
给led两端加电压呀!
聪明,就是在led灯珠的两个管脚加上电压。让左右两边产生电压差,电流就产生了,于是Led就发光了。
好,旁边一个聪明的兄弟来精神了,加电压吗?太方便了,马上直接整个220给加上去了。
结果你肯定能猜测到了。“机毁人亡”。
对了,刚才忘了提醒一下了,我们采用的这种小Led的他的工作电流很小,用不了220v这头大牛!
常见的小led的参数如下:
直径 3mm 插件LED
额定电流都是 20 mA,使用是电流 15 mA。
红黄灯珠电压是 1.8V-2.2V,
蓝绿白灯珠电压是 3.0V-3.6V。
直径 5mm 插件LED
工作电流是10mA,
电压1.6V左右。
因为工作电流小,点亮电压低,用我们的pi2的gpio可以直接点亮它,不需要外加任何驱动。
知道我为什么要选这种led做实验了吧!
大概解释一下,这个原理图:
板子上电后,电源管理芯片开始工作,于是vdd_sys_3.3v开始出现,对于pwr led ,左端3.3v,右端接地,左右两端形成电流,于是开始发光。这就是问什么我们接上供电后,电源指示灯,就一直发光的原因。
   而对于stat led ,情况就不同了,如果led1引脚在这时被送过来3.3v的电压,led等左右两边无法形成电压差,也就没有电流产生,也就不会发光。
    反过来说,如果我们给led1针脚送去不同周期的高低电平,此led就会交替闪烁。
这就是我们控制led灯发光的基本原理。
Ok
喝口水,回来继续。
   好了,
再看看原理图,我们拿板载的led为例,来验证咱们前面的分析,看看正确与否。
03.PNG
04.PNG
从这两个图上不难看出,我们的Led1连接在gpiob12上,根据前面的分析,我们只要给这个引脚放置一个低电平,就可以让这个led1点亮了。如果给它让这个电平出现周期性的变化,那么这个led1也就跟着发生周期性的明暗交替变化。
老规矩,先看原理图。
05.PNG
注意不同gpio口的基地址,和需要设置的寄存器功能。
我们这次主要是设置gpio的B口,输出高低电平。
因此,主要看和B口控制寄存器和地址寄存器相关的设置内容就可以了。
我们需要gpio作为输出功能用,因此,看看15.3.2ououtput operation这节。
06.PNG
再看看gpio映射的地址
07.PNG
Ok,根据以前编写单片机程序的经验,我们的裸机程序需要有头文件,c语言源文件。
根据以往的arm芯片的编程经验,我们的裸机程序,比单片机程序还要多增加一个汇编语言源文件作为程序的入口。
下面卡是准备程序:
为了方便,我参考了网友“哀其不幸”的程序,根据我们的小pi2,略作修改。
需要3个程序:
一个启动启动的汇编程序start.s,一个头文件gpio.h,一个主程序main.c。
源程序如下:
Start.s
  b start
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
start:
b main
gpio.h
#defineGPIOBOUT (*(volatile unsigned *) 0xc001b000)       //GPIOB引脚输出电平设置
#defineGPIOBOUTENB (*(volatile unsigned *)0xc001b004)    //GPIOB引脚IO模式选择,0-输入模式,1-输出模式
#defineGPIOBALTFN0 (*(volatile unsigned *)0xc001b020)    //GPIOB(0-15)引脚功能选择,00-普通IO功能
Main.c
#include"gpio.h"
#defineLED1ON GPIOBOUT |= 0x01
#defineLED1OFF GPIOBOUT &= ~(0x1<<0)
voiddelay(unsigned int count)
{
    while(count--);
}
voidmain(void)
{
    /*初始化GPIOB*/
    GPIOBALTFN0 &=~((0x3<<0)|(0x3<<2)|(0x3<<4));
    GPIOBOUTENB |= 0x07;
    GPIOBOUT &= ~(0x7);
    while(1)
    {
        LED1ON;
        delay(2000000);
        LED1OFF;
    }
}
分别建立这3个文件后。
单独编译他们。
arm-linux-gcc -c start.s -o start.o
arm-linux-gcc -c main.c -o main.o
arm-linux-ld -Ttext=0x42C00000 start.omain.o -o main
arm-linux-objcopy -I elf32-littlearm -Obinary main main.bin
有眼睛尖的同学肯定要问了,你这个0x42C00000怎么来的。为什么要选这个地址。
好,听我慢慢道来。
我们先不烧写程序,先来做个试验。
就是先做个启动系统的最小化sd卡。
这张卡里面只包括:2ndboot镜像。
三、单独启动pi2的系统的最小化的镜像sd卡制作。
制作sd卡的工具有很多,我们用广受好评的winhex来做吧。这个工具在数据恢复领域使用很广。不知有多少死亡的数据因为它儿起死回生。不知挽救了多少粗心大意的网管的命。
首先用winhex打开友善官方镜像如下图:
11.PNG
alt+g 输入200,(注意后面的十六进制,十进制的切换方法·是偺offset处点击鼠标。)
点击确定,在光标闪烁的位置,点击右键,alt+1, 选中要复制的起始块位置,
重复上面的alt+g 输入8200
12.PNG
点击右键,alt+2, 选中要复制的结束块位置,(注意此处选择81ff处作为结束块。)
右键点击 编辑》复制选块-》十六进制数值。
13.PNG
此时0x200-0x81ff的数据已经进入到剪贴板里面。
接下来,
winhex顶部打开 工具-》打开磁盘-》选中我们已经彻底格式化的sd卡。
14.PNG
点击确定
同样的方法走到,sd卡的0x200偏移处。
15.PNG
右键点击 编辑-》剪贴板数据-》写入-》确定。
16.PNG
回到winhex顶部,点击保存,把改变的数据写入sd卡。
到此,我们能启动pi2的最小化系统只做好了。
dos时代的那个sysc: 复杂多了吧!
难怪懂嵌入式系统的人越来越少了呢?
原来是工具越来越复杂了。
好了,把这张卡插入我们的小pi2Stopstopstop。先别急着通电
把串口连接到我们的主电脑,看看串口有什么鬼再说吧。
什么?为什么要用串口,因为,没有别的调试方法啊!
我们的小pi2太小了,没有引出任何调试接口啊!
好了,开机,看看串口有什么东东输出来没有。
17.PNG
全部的信息如下:
--------------------------------------------------------------------------------
Second Boot byNexell Co. : Built on Nov 19 2014 20:10:38
--------------------------------------------------------------------------------
PLL0: 550000000PLL1: 1200000000 PLL2: 800000000 PLL3: 612000000
Divider0 PLL: 1CPU:1200000000 CPU BUS:300000000
Divider1 PLL: 2BCLK:400000000 PCLK:200000000
Divider2 PLL: 2MDCLK:800000000 MCLK:800000000
MBCLK:400000000MPCLK:200000000
Divider3 PLL: 0G3D BCLK:550000000
Divider4 PLL: 2MPEG BCLK:400000000 MPEG PCLK:200000000
123
DDR3 POR InitStart
phy init
##########READ/GATE Level ##########
DDR3 Init Done!
Loading fromsdmmc...
Image LoadingDone!
Launch to0x42C00000
从串口输出的信息看,我们确实是运行在2ndboot里面了。
0x42C00000这个地址要记住,如果我们的裸机测试程序,需要用友善的2nduboot引导,那么链接时要指向这个地址。
好了,这回知道我们为什么要把上面程序的链接地址指向这里了吧!
这样保证我们的程序在2ndboot交出控制权后,我们的程序能顺利执行。
四、用2ndboot+裸机程序烧sd卡,引导pi2的测试
好了,把编译过的裸机程序main.bin放到sd卡上去吧。
位置就是我们uboot存放的位置处,偏移地址0x8200的后面。
操作过程一样,就是打开的文件是main.bin,全部复制main.bin上的所有文件,十六进制复制,sd卡偏移起始地址选择0x8200.最后别忘了存盘。
   再次用这个2ndboot+main.bin制作的sd卡引导pi2吧!
果然不出所料,我们的小pi2终于开始闪烁着迷人的蓝色光芒了。
怎一个爽字得了!
结束了,回家吃饭!
别的!
还没完呢?
我们还没测试用main.bin 替代2ndboot后能不能运行我们的逻辑程序呢!
革命尚未完全成功,通知仍需努力!
五、用main.bin 替代2ndboot引导我们的小pi2的测试
用我们的裸机程序代替2ndboot,看看运行效果如何。
Ok,首先先彻底格式化sd卡,插到小pi2上看看串口输出结果。
18.PNG
有看官说了,大哥你别逗了!哪里有显示啊!
没上显示就对了,因为还没有程序运行呢?
internalrom 抓不到东西运行啊!
个人猜测,土财主三星没有在internal rom里面写串口通讯程序,所以串口没法显示。
不过能理解三星也不知道我们的小pi2要用哪几个口做串口通讯用啊!
所以也就没办法写这个程序了。
这样解释你该满意了吧。
(nnd,我第一次实验的时候在这个地方卡了2天多,一直以为是裸机程序有问题,那个汗哪。。。。。。)
既然如此,那是不是就不能做实验了呢?
Nonono,既然internal rom 能把2ndboot搬移到sram里面执行,那我把我的裸机程序放在2ndboot的位置代替它,没有理由不被internal rom给搬到iram里面去运行啊!
行不行的,试试再说。
说到实验,那问题们马上又来了,我们自己的程序链接地址用哪个?
总不能靠掷色子决定吧!
别急!咱不是有红宝书吗?
打开红宝书,翻到14章第三节
19.PNG
这里明确告诉我们了internal rom 的地址是0xffff0000,哪就好办了,把我们的链接地址指向这里,我们的裸机程序被搬搬运到这里后,不就能自己运行了么!
太聪明了!
重复上面的过程,
arm-linux-gcc -c start.s -o start.o
arm-linux-gcc -c main.c -o main.o
arm-linux-ld -Ttext=0xffff0000 start.o main.o -o main
arm-linux-objcopy -I elf32-littlearm -Obinary main main.bin
注意啊,链接地址改成这个了。
再把生成的main.binwinhex放到SD卡的的0x400位置处,对,这里就是2ndboot的老家。
根据前面的partmap.txt文件内容,我开始尝试的是存放到0x200处。一直不成功,后来请教了一个前辈,才开始试验过这个地址。
插卡,上电,果然不出所料,小pi2小蓝眼睛眨得依然那么迷人。
至此,我们的实验都成功了。
总结与疑惑:
1、  我们可以通过替换官方提供的2ndboot、u_boot来达到运行我们自己的裸机程序的目的。
2、  截取友善官方镜像时,发了一个NISH标志,请教友善的客服,没有理睬我,后来靠度娘查到了网友的文章,原来是存放配置信息 ,包括(启动方式,PLL,DDR)。在这里吐槽一下友善的售后,不是说东西便宜,你就可以不用理睬客户的咨询了。人心伤了,在弥合就难了。
3、  由于internalrom没有源代码,没有串口输出,小pi2又没有引出调试接口,无从知道它运行完后,程序会跑到哪里执行,只能靠datasheet反复做实验验证,最后还是靠网友的帮助才成功。这里我要吐槽一下三星,这玩意又不涉及商业机密,你提供一个地址得节省我多少时间啊。
4、 在ubuntu下烧写的sd卡的partmap.txt和windows下所给的镜像扇区位置不一致。位置有重叠,咨询了友善的售后,你知道结果的。我在这里浪费了一周的时间。才把裸机程序运行起来。算了,我懒得吐槽了,谁让我不熟悉这个片子呢!
5、 土财主三星的Datasheet的资料不够详细,尤其关于引导部分的,说到这里我要表扬一下友善的攻城狮,就凭借这本小册子就把android跑起来了。这水平那就不是用牛字能评价的了。
6、 悬而未局的问题,网友怎么知道NISH.txt的内容的,反编译吗?
总之,折腾的过程就是折腾,折腾,再折腾!
我享受这个过程!
不韶了,愿意听我韶的同学,下篇再见。

标签:程序
ypw

技术员

发表于 2016-1-23 00:29:11  

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
我的天,写得好长呀
还是在linux里玩寄存器比较方便
回复

点赞

实习生

发表于 2016-1-23 03:39:54   来自手机
谢谢分享。。。。
初学者 完全没有太多门路 。。。。对了 楼主在pi2跑安卓和debian选择关机 lcd屏都会卡到关机那一时刻的画面 无法关机 是因为没有电源管理芯片的问题吗 电源管理芯片可以通过预留的40pin gpio再接吗
回复

点赞

社区之星

发表于 2016-1-31 20:16:16  
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000

中间那段我的试用帖也有,不过不知道,要这么多    .word 0x00000000 有何用、、
回复

点赞

技术员

发表于 2016-1-31 20:48:08    楼主|
擦肩的阳光 发表于 2016-1-31 20:16
.word 0x00000000
    .word 0x00000000
    .word 0x00000000

不多啊,刚好7个啊!
回复

点赞

社区之星

发表于 2016-1-31 20:49:12  
是 NSIH.txt吧??
回复

技术员

发表于 2016-1-31 20:54:00    楼主|
是的,exception vector
回复

社区之星

发表于 2016-1-31 22:25:51  
chengtao 发表于 2016-1-31 20:48
不多啊,刚好7个啊!

额。。为什么要7个呢?
还有个问题,2ndboot.bin 既然不提供源码,那友善是怎么做成镜像的。。。
回复

点赞

社区之星

发表于 2016-1-31 22:29:51  
这个42c00000是友善定的吗?
回复

点赞

技术员

发表于 2016-1-31 22:50:41    楼主|
擦肩的阳光 发表于 2016-1-31 22:25
额。。为什么要7个呢?
还有个问题,2ndboot.bin 既然不提供源码,那友善是怎么做成镜像的。。。

你看看友善编译uboot的脚本吧!能找到蛛丝马迹,友善的攻城狮是不会回答这种问题的。我也是自己连猜带蒙,外加百度的!
回复

点赞

技术员

发表于 2016-1-31 22:56:47    楼主|
擦肩的阳光 发表于 2016-1-31 22:29
这个42c00000是友善定的吗?

这个我也不确定,可能是友善做了什么搬运。我查过其他家的4418板子,2ndboot运行后的地址,不是这里。不过也可能其他家做了什么搬移。不过能肯定的是,我们自己的裸机程序,链接到这里,可以正确执行。
回复

点赞

高级工程师

发表于 2016-2-1 06:01:15  
一起学习、共同进步、共同提高、共同成长!
回复

点赞

技术员

发表于 2016-2-1 17:14:51    楼主|
sinap_zhj 发表于 2016-2-1 06:01
一起学习、共同进步、共同提高、共同成长!

一起学习、共同进步、共同提高、共同成长!
感谢网站提供了这么好的论坛给我们交流!
回复

点赞

高级工程师

发表于 2016-2-2 07:06:02  
是的。大家一起努力吧,争取更大的进步。
回复

点赞

实习生

发表于 2016-3-2 11:05:04  
楼主能讲解一下不要2ndboot为什么要把程序烧写到0x400,是什么原因,谢谢了!!!
回复

点赞

技术员

发表于 2016-3-11 15:00:52    楼主|
kai540693711 发表于 2016-3-2 11:05
楼主能讲解一下不要2ndboot为什么要把程序烧写到0x400,是什么原因,谢谢了!!!

看前面的介绍吧,写的很详细了。有些是通过实验得到的结论
回复

点赞

实习生

发表于 2016-3-14 17:12:36  
运行不成功啊!!!!!!!!!!!!!!!!
回复

技术员

发表于 2016-3-17 10:37:44    楼主|
873204147 发表于 2016-3-14 17:12
运行不成功啊!!!!!!!!!!!!!!!!

对着步骤仔细查一查。
回复

点赞

实习生

发表于 2016-5-9 23:26:31  
楼主,main.c是不是漏了个 delay(2000000);  眼睛一直都是亮的  

添上才可以看到迷人的放电蓝眼睛

#include"gpio.h"
#defineLED1ON GPIOBOUT |= 0x01
#defineLED1OFF GPIOBOUT &= ~(0x1<<0)
voiddelay(unsigned int count)
{
    while(count--);
}
voidmain(void)
{
    /*初始化GPIOB*/
    GPIOBALTFN0 &=~((0x3<<0)|(0x3<<2)|(0x3<<4));
    GPIOBOUTENB |= 0x07;
    GPIOBOUT &= ~(0x7);
    while(1)
    {
        LED1ON;
        delay(2000000);
        LED1OFF;
        delay(2000000);
    }
}
回复

点赞

实习生

发表于 2017-2-5 12:46:41  
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
回复

点赞

12下一页
高级模式
您需要登录后才可以回帖 登录 | 注册

专家问答 查看更多>>
关闭

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

小黑屋|手机版|Archiver| 电子发烧友 ( 粤ICP备14022951号-2 )     

GMT+8, 2017-5-27 08:29 , Processed in 0.149101 second(s), 13 queries , Memcache On.

微信扫描
快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

我的提问

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

-

硬件设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PCB设计论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

树莓派论坛

智能硬件论坛

开发快智能硬件开发平台

Intel物联网开发者专区

Waveshare

乐美客SBC专区

Arduino论坛

BeagleBone论坛

机器人论坛

创客神器NanoPi

小钢炮CANNON

比派科技banana pi专区

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

个人版区

阿东Verilog技术专版

直流马达驱动电路设计

LabVIEW英雄联盟

特权同学FPGA专区

-

厂商专区

灵动微电子 MM32

盈鹏飞嵌入式

TI论坛

TI Deyisupport社区

芯灵思嵌入式论坛

Tisan

米尔科技

庆科社区

WIZnet技术专区

Cypress技术论坛

飞凌嵌入式

Qualcomm技术论坛

英创嵌入式

机智云GoKit论坛

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区