IT培训机构|91免费精品视频|专注编程培训|91免费精品|软件开发培训_91免费国产视频_华清远见教育

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > linux中斷編程、中斷編程詳解

linux中斷編程、中斷編程詳解 時間:2018-07-27      來源:未知

Linux中斷處理驅(qū)動程序編寫

中斷處理是操作系統(tǒng)必須具備的上要功能之一,下面我們一起來探討一下Linux中的中斷處理。

1. 什么是中斷

中斷就是CPU正常運行期間,由于內(nèi)、外部事件引起的CPU暫時停止正在運行的程序,去執(zhí)行該內(nèi)部事件或外部事件的引起的服務(wù)中去,服務(wù)執(zhí)行完畢后再返回斷點處繼續(xù)執(zhí)行的情形。這樣的中斷機制極大的提高了CPU運行效率。

1.1. 中斷的分類:

1) 根據(jù)中斷的來源可分為內(nèi)部中斷和外部中斷,內(nèi)部中斷的中斷源來自于CPU內(nèi)部(軟件中斷指令、溢出、除法錯誤等),例如操作系統(tǒng)從用戶態(tài)切換到內(nèi)核態(tài)需要借助CPU內(nèi)部的軟件中斷,外部中斷的中斷源來自于CPU外部,由外設(shè)觸發(fā)。

2) 根據(jù)中斷是否可以被屏蔽,中斷可分為可屏蔽中斷和不可屏蔽中斷,可屏蔽中斷可以通過設(shè)置中斷控制器寄存器等方法被屏蔽,屏蔽后,該中斷不再得到響應(yīng),而不可屏蔽中斷不能被屏蔽。

3) 根據(jù)中斷入口跳轉(zhuǎn)方式的不同,中斷可分為向量中斷和非向量中斷。采用向量中斷的CPU通常為不同的中斷分配不同的中斷號,當(dāng)檢測到中斷的中斷號到來時,就自動跳轉(zhuǎn)到該中斷對應(yīng)的地址處去執(zhí)行程序。不同的中斷號對應(yīng)不同的中斷入口地址。非向量中斷的多個中斷共享一個入口程序處理入口地址,中斷程序跳轉(zhuǎn)到該入口地址執(zhí)行時,再通過中斷程序來判斷中斷標(biāo)志來識別具體是哪一個中斷,也就是說向量中斷由硬件提供中斷服務(wù)程序入口地址,非向量中斷由軟件提供中斷服務(wù)程序入口地址。

4) 非向量中斷處理流程:

/*典型的非向量中斷首先會判斷中斷源,然后調(diào)用不同中斷源的中斷處理程序*/

irq_handler()

{

...

int int_src = read_int_status();/*讀硬件的中斷相關(guān)寄存器*/

switch(int_src)

{

//判斷中斷標(biāo)志

case DEV_A:

dev_a_handler();

break;

case DEV_B:

dev_b_handler();

break;

...

default:

break;

}

...

}

2. linux中斷頂部、底部概念

為保證系統(tǒng)實時性,中斷服務(wù)程序必須足夠簡短,但實際應(yīng)用中某些時候發(fā)生中斷時必須處理大量的工作,這時候如果都在中斷服務(wù)程序中完成,則會嚴(yán)重降低中斷的實時性,基于這個原因,linux系統(tǒng)提出了一個概念:把中斷服務(wù)程序分為兩部分:頂半部、底半部。

2.1. 頂半部

完成盡可能少的比較急的功能,它往往只是簡單的讀取寄存器的中斷狀態(tài),并清除中斷標(biāo)志后就進(jìn)行“中斷標(biāo)記”(也就是把底半部處理程序掛到設(shè)備的底半部執(zhí)行隊列中)的工作。特點是響應(yīng)速度快。

2.2. 底半部

中斷處理的大部分工作都在底半部,它幾乎做了中斷處理程序的所有事情。 特點:處理相對來說不是非常緊急的事件 ,底半部機制主要有:tasklet、工作隊列和軟中斷。

Linux中查看/proc/interrupts文件可以獲得系統(tǒng)中斷的統(tǒng)計信息:

中斷編程

3. Linux中斷編程

3.1. 申請和釋放中斷

3.1.1. 申請中斷:

int request_irq(unsigned int irq,irq_handler_t handler,unsigned long irqflags,const char *devname,void *dev_id);

參數(shù)介紹:irq是要申請的硬件中斷號。

Handler:是向系統(tǒng)登記的中斷處理程序(頂半部),是一個回調(diào)函數(shù),中斷發(fā)生時,系統(tǒng)調(diào)用它,將dev_id參數(shù)傳遞給它。

irqflags:是中斷處理的屬性,可以指定中斷的觸發(fā)方式和處理方式:

觸發(fā)方式:IRQF_TRIGGER_RISING、IRQF_TRIGGER_FALLING、IRQF_TRIGGER_HIGH、IRQF_TRIGGER_LOW,處理方式:IRQF_DISABLE表明中斷處理程序是快速處理程序,快速處理程序被調(diào)用時屏蔽所有中斷,IRQF_SHARED表示多個設(shè)備共享中斷,dev_id在中斷共享時會用到,一般設(shè)置為NULL。

返回值:為0表示成功,返回-EINVAL表示中斷號無效,返回-EBUSY表示中斷已經(jīng)被占用,且不能共享。

頂半部的handler的類型irq_handler_t定義為:

typedef irqreturn_t (*irq_handler_t)(int,void*);

typedef int irqreturn_t;

3.1.2. 釋放IRQ

有請求當(dāng)然就有釋放。中斷的釋放函數(shù)為:

void free_irq(unsigned int irq,void *dev_id);

參數(shù)定義與request_irq類似。

3.1.3. 中斷的使能和屏蔽

void disable_irq(int irq);//等待目前中斷處理完成(最好別在頂板部使用,你懂得)

void disable_irq_nosync(int irq);//立即返回

void enable_irq(int irq);//

3.1.4. 屏蔽本CPU內(nèi)所有中斷:

#define local_irq_save(flags)...//禁止中斷并保存狀態(tài)。

void local_irq_disable(void); //禁止中斷,不保存狀態(tài)。

下面來分別介紹一下頂半部和底半部的實現(xiàn)機制

3.1.5. 底半部機制:

簡介:底半部機制主要有tasklet、工作隊列和軟中斷

3.1.5.1. 底半部實現(xiàn)方法之一tasklet

(1) 我們需要定義tasklet機器處理器并將兩者關(guān)聯(lián),例如:

void my_tasklet_func(unsigned long);/*定義一個處理函數(shù)*/

DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);

/*上述代碼定義了名為my_tasklet的tasklet并將其與my_tasklet_func()函數(shù)綁定,傳入的參數(shù)為data*/

(2)調(diào)度

tasklet_schedule(&my_tasklet);

//使用此函數(shù)就能在是當(dāng)?shù)臅r候進(jìn)行調(diào)度運行

(3)tasklet使用模板:

/*定義tasklet和底半部函數(shù)并關(guān)聯(lián)*/

void xxx_do_tasklet(unsigned long);

DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet,0);

/*中斷處理底半部*/

void xxx_do_tasklet(unsigned long)

{

...

}

/*中斷處理頂半部*/

irqreturn_t xxx_interrupt(int irq,void *dev_id)

{

...

tasklet_schedule(&xxx_tasklet);//調(diào)度地半部

...

}

/*設(shè)備驅(qū)動模塊加載函數(shù)*/

int __init xxx_init(void)

{

...

/*申請中斷*/

result = request_irq(xxx_irq,xxx_interrupt, IRQF_DISABLED,"xxx",NULL);

...

return IRQ_HANDLED;

}

/*設(shè)備驅(qū)動模塊卸載函數(shù)*/

void __exit xxx_exit(void)

{

...

/*釋放中斷*/

free_irq(xxx_irq,xxx_interrupt);

...

}

3.1.5.2. 底半部實現(xiàn)方法之二---工作隊列

使用方法和tasklet類似,相關(guān)操作:

struct work_struct my_wq;/*定義一個工作隊列*/

void my_wq_func(unsigned long);/*定義一個處理函數(shù)*/

通過INIT_WORK()可以初始化這個工作隊列并將工作隊列與處理函數(shù)綁定INIT_WORK(&my_wq,(void (*)(void *))my_wq_func,NULL);/*初始化工作隊列并將其與處理函數(shù)綁定*/

schedule_work(&my_wq);/*調(diào)度工作隊列執(zhí)行*/

/*工作隊列使用模板*/

/*定義工作隊列和關(guān)聯(lián)函數(shù)*/

struct work_struct(unsigned long);

void xxx_do_work(unsigned long);

/*中斷處理底半部*/

void xxx_do_work(unsigned long)

{

...

}

/*中斷處理頂半部*/

irqreturn_t xxx_interrupt(int irq,void *dev_id)

{

...

schedule_work(&my_wq);//調(diào)度底半部

...

return IRQ_HANDLED;

}

/*設(shè)備驅(qū)動模塊加載函數(shù)*/

int xxx_init(void)

{

...

/*申請中斷*/

result = request_irq(xxx_irq,xxx_interrupt,IRQF_DISABLED,"xxx",NULL);

...

/*初始化工作隊列*/

INIT_WORK(&my_wq,(void (*)(void *))xxx_do_work,NULL);

}

/*設(shè)備驅(qū)動模塊卸載函數(shù)*/

void xxx_exit(void)

{

...

/*釋放中斷*/

free_irq(xxx_irq,xxx_interrupt);

...

}

4. 中斷共享

中斷共享是指多個設(shè)備共享一根中斷線的情況,中斷共享的使用方法:

(1).在申請中斷時,使用IRQF_SHARED標(biāo)識;

(2).在中斷到來時,會遍歷共享此中斷的所有中斷處理程序,直到某一個函數(shù)返回IRQ_HANDLED,在中斷處理程序頂半部中,應(yīng)迅速根據(jù)硬件寄存器中的信息參照dev_id參數(shù)判斷是否為本設(shè)備的中斷,若不是立即返回IR1_NONE

/*共享中斷編程模板*/

irqreturn_t xxx_interrupt(int irq,void *dev_id,struct pt_regs *regs)

{

...

int status = read_int_status();/*獲知中斷源*/

if(!is_myint(dev_id,status))/*判斷是否為本設(shè)備中斷*/

return IRQ_NONE;/*不是本設(shè)備中斷,立即返回*/

/*是本設(shè)備中斷,進(jìn)行處理*/

...

return IRQ_HANDLED;/*返回IRQ_HANDLER表明中斷已經(jīng)被處理*/

}

/*設(shè)備模塊加載函數(shù)*/

int xxx_init(void)

{

...

/*申請共享中斷*/

result = request_irq(sh_irq,xxx_interrupt,IRQF_SHARE,"xxx",xxx_dev);

...

}

/*設(shè)備驅(qū)動模塊卸載函數(shù)*/

void xxx_exit()

{

...

/*釋放中斷*/

free_irq(xxx_irq,xxx_interrupt);

...

}

5. 內(nèi)核定時器

內(nèi)核定時器編程:

簡介:軟件意義上的定時器最終是依賴于硬件定時器實現(xiàn)的,內(nèi)核在時鐘中斷發(fā)生后檢測各定時器是否到期,到期后定時器處理函數(shù)作為軟中斷在底半部執(zhí)行。

Linux內(nèi)核定時器操作:

5.1. timer_list結(jié)構(gòu)體

每一個timer_list對應(yīng)一個定時器

struct timer_list{

struct list_head entry;/*定時器列表*/

unsigned long expires;/*定時器到期時間*/

void (*function)(unsigned long);/*定時器處理函數(shù)*/

unsigned long data;/*作為參數(shù)被傳遞給定時器處理函數(shù)*/

struct timer_base_s *base;

...

};

當(dāng)定時器滿的時候,定時器處理函數(shù)將被執(zhí)行

5.2. 初始化定時器

void init_timer(struct timer_list * timer);

//初始化timer_list的entry的next為NULL,并給base指針賦值。

TIMER_INITIALIZER(_function,_expires,_data);//此宏用來

//賦值定時器結(jié)構(gòu)體的function、expires、data和base成員

#define TIMER_INITIALIZER(function,_expires,_data)

{

.entry = {.prev = TIMER_ENTRY_STATIC},\

.function= (_function), \

.expires = (_expire), \

.data = (_data), \

.base = &boot_tvec_bases,\

}

DEFINE_TIMER(_name,_function,_expires,_data)//定義一個定時器結(jié)構(gòu)體變量//并為此變量取名_name

//還有一個setup_timer()函數(shù)也可以用于定時器結(jié)構(gòu)體的初始化。

5.3. 增加定時器

void add_timer(struct timer_list * timer);//注冊內(nèi)核定時器,也就是將定時器加入到內(nèi)核動態(tài)定時器鏈表當(dāng)中。

5.4. 刪除定時器

del_timer(struct timer_list *timer);

del_timer_sync()//在刪除一個定時器時等待刪除操作被處理完(不能用于中斷上下文中)

5.5. 修改定時器expires

int mod_timer(struct timer_list * timer,unsigned long expires);//修改定時器的到期時間

/*內(nèi)核定時器使用模板*/

/*xxx設(shè)備結(jié)構(gòu)體*/

struct xxx_dev

{

struct cdev cdev;

...

timer_list xxx_timer;/*設(shè)備要使用的定時器*/

};

/*xxx驅(qū)動中的某函數(shù)*/

xxx_funcl(...)

{

struct xxx_dev *dev = filp->private_data;

...

/*初始化定時器*/

init_timer(&dev->xxx_timer);

dev->xxx_timer.function = &xxx_do_timer;

dev->xxx_timer.data = (unsigned long)dev;

/*設(shè)備結(jié)構(gòu)體指針作為定時器處理函數(shù)參數(shù)*/

dev->xxx_timer.expires = jiffes + delays;

/*添加(注冊)定時器*/

add_timer(&dev->xxx_timer);

...

}

/*xxx驅(qū)動中的某函數(shù)*/

xxx_func2(...)

{

...

/*刪除定時器*/

del_timer(&dev->xxx_timer);

...

}

/*定時器處理函數(shù)*/

static void xxx_do_timer(unsigned long arg)

{

struct xxx_device *dev = (struct xxx_device *)(arg);

...

/*調(diào)度定時器再執(zhí)行*/

dev->xxx_timer.expires = jiffes + delay;

add_timer(&dev -> xxx_timer);

...

}

//定時器到期時間往往是在jiffies的基礎(chǔ)上添加一個時延,若為HZ則表示延遲一秒

5.6. 內(nèi)核中的延遲工作:

簡介:對于這種周期性的工作,Linux提供了一套封裝好的快捷機制,本質(zhì)上利用工作隊列和定時器實現(xiàn),這其中用到兩個結(jié)構(gòu)體:

(1)struct delayed_work

{

struct work_struct work;

struct timer_list timer;

};

(2) struct work_struct

{

atomic_long_t data;

...

}

相關(guān)操作:

int schedule_delay_work(struct delayed_work *work,unsigned long delay);//當(dāng)指定的delay到來時delay_work中的work成員的work_func_t類型成員func()會被執(zhí)行work_func_t類型定義如下:

typedef void (*work_func_t)(struct work_struct *work);//delay參數(shù)的單位是jiffes

mescs_to_jiffies(unsigned long mesc);//將毫秒轉(zhuǎn)化成jiffes單位

int cancel_delayed_work(struct delayed_work *work);

int cancel_delayed_work_sync(struct delayed_work *work);//等待直到刪除(不能用于中斷上下文)

內(nèi)核延遲的相關(guān)函數(shù):

短延遲:

Linux內(nèi)核提供了如下三個函數(shù)分別進(jìn)行納秒、微妙和毫秒延遲:

void ndelay(unsigned long nsecs);

void udelay(unsigned long usecs);

void mdelay(unsigned long msecs);

機制:根據(jù)CPU頻率進(jìn)行一定次數(shù)的循環(huán)(忙等待)

注意:在Linux內(nèi)核中最好不要使用毫秒級的延時,因為這樣會無謂消耗CPU的資源。

對于毫秒以上的延時,Linux提供如下函數(shù):

void msleep(unsigned int millisecs);

unsigned long msleep_interruptible(unsigned int millisecs);//可以被打斷

void ssleep(unsigned int seconds);

//上述函數(shù)使得調(diào)用它的進(jìn)程睡眠指定的時間

長延遲:

機制:設(shè)置當(dāng)前jiffies加上時間間隔的jiffies,直到未來的jiffies達(dá)到目標(biāo)jiffires

/*實例:先延遲100個jiffies再延遲2s*/

unsigned long delay = jiffies + 100;

while(time_before(jiffies,delay));

/*再延遲2s*/

unsigned long delay = jiffies + 2*Hz;

while(time_before(jiffies,delay));//循環(huán)直到到達(dá)指定的時間與timer_before()相對應(yīng)的還有一個time_after

睡著延遲:

睡著延遲是比忙等待更好的一種方法

機制:在等待的時間到來之前進(jìn)程處于睡眠狀態(tài),CPU資源被其他進(jìn)程使用,實現(xiàn)函數(shù)有:

schedule_timeout()

schedule_timeout_uninterruptible()

其實在短延遲中的msleep() msleep_interruptible()

本質(zhì)上都是依賴于此函數(shù)實現(xiàn)的,下面兩個函數(shù)可以讓當(dāng)前進(jìn)程加入到等待隊列中,從而在等待隊列上睡眠,當(dāng)超時發(fā)生時,進(jìn)程被喚醒

sleep_on_timeout(wait_queue_head_t *q,unsigned long timeout);

interruptible_sleep_on_timeout(wait_queue_head_t *q,unsigned long timeout);

上一篇:詳解格式化輸入函數(shù)scanf

下一篇:Linux應(yīng)用程序幾種參數(shù)傳遞方式

熱點文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: 气动球阀,电动蝶阀,调节阀,衬氟阀门,水利控制阀,大口径阀门生产厂家-上海百钢阀门集团有限公司-官网,上海阀门品牌 | 液体灌装机-酱料灌装机-全自动灌装机-旋盖机-铝箔封口机-贴标机厂家-迈特威自动化设备(天津)有限公司" | 太阳能光伏发电_太阳能热水器_空气能热水器_直饮净水器_深圳市大兴节能环保科技有限公司 | 铁三角话筒-思美音频处理器-艾伦赫赛数字调音台-北京盛世音盟电子科技有限公司 | 无塔供水_无塔供水设备_全自动_石家庄工泉水处理设备有限公司_家用无塔供水器 | 中深世纪广告公司 深圳标志设计,深圳logo设计公司,包装设计公司,深圳商标设计,深圳画册设计公司 中商信息网-商务数据网-中文商务数据网 | 行李快递安检机-便携式X光安检仪-行李安检机-液体-爆炸物探测仪-安天下安检设备 | 网带式等温正火生产线_燃气式铝合金加热炉_燃气式烘干窑炉-湖州中科炉业科技有限公司 | 河南车用尿素设备_郑州车用尿素设备_河南江宇环保车用尿素液厂家 | 塑料模具公司,塑料包装桶厂家,PET打包带厂家,缠绕膜厂家-新疆福吉亚工贸有限公司 | 节能设备|余热回收|蒸汽压缩机|脱硝-河北耀一节能设备制造有限责任公司 | 铨盛国际供应链-PC增韧剂/硅系增韧剂/耐寒增韧剂/耐化学增韧剂 | 学汽修_汽修学校_汽修学校哪家好-江西万通汽车学院官网 | 西安测试仪-西安电压测试仪-西安电流测试仪-西安热油汽水测试仪-西安阻抗测试仪-西安时间速度测试仪-西安电力设备厂家-西安中洲电力设备有限公司 | 数海经纬官方网站 - 声学智能领域先行者 - 数海经纬(深圳)信息技术有限公司 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 激光焊接不锈钢翅片管,不锈钢翅片管,激光焊接复合翅片管,南通拓帆换热设备有限公司 | 山东礼品盒,礼品盒生产厂家,礼品包装盒厂家-济南恒印包装有限公司 | 模压机|硫化机|平板硫化机生产厂家-南通海利特橡塑机械有限公司 模压化粪池_三格式化粪池_玻璃钢化粪池厂家 | 树枝粉碎机,锯末机,木材粉碎机的专业生产厂家利鑫机械,问价格找利鑫 | 机锋网-畅享科技品质生活,尽在机锋网 | 深圳办公室装修_高端写字楼设计费用_企业装修报价公司-深圳长红装饰 | 京建鹏达_商用无烟烧烤设备多少钱|开店商用自助旋转烧烤炉价格|无烟电烧烤炉批发厂家|无烟烧烤桌定做厂商-京建鹏达烧烤设备网 | 中国水泥协会-官方网站| 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 重庆消杀公司-重庆斗哥环保科技-灭鼠公司-重庆灭蟑螂-除四害-灭老鼠-灭虫-重庆灭白蚁公司 | 上海钧尚电器有限公司 - Faulhaber电机 AMETEK pittman电机 AMETEK ROTRON军用航空风机 Exlar电动缸 MAE电机 MCG电机 CP电动工具 马头工具 AMCI驱动器 直流电机 减速箱 直流伺服电机,无刷电机,直线电机 直流防爆电机 防爆电机 汽车助力转向电机 EPS电机 faulhaber motor faulhaber gearbox NANOTEC电机 ELWOOD电机 PHYTRON电机 EXLAR伺服电动缸 高力矩、高性能直流电机,音圈电机,风机,直流风机,航空风机 | 武汉凯美隆窗帘厂家_定做商用窗帘_家用遮阳帘_涵盖电动窗帘_天棚帘_遮阳棚_凯美隆-专注遮阳产品 武汉净化机-武汉全热新风换气机-武汉静音送风机-武汉东信新风节能设备有限公司 | 武汉不锈钢水箱厂家_武汉不锈钢消防水箱定做批发_武汉不锈钢消防水箱加工厂 | 深圳展厅设计_产业园区展馆设计_展馆设计公司_健康产业展馆设计_展厅设计哪家好_华竣国际 | 鸟语林-百鸟园-不锈钢丝绳网-钢丝网-瓦片防坠网-围网-河北中重钢结构工程有限公司 | 消防施工,消防工程施工,消防施工改造-北京消防工程公司-亿杰(北京)消防工程有限公司 | 山西洗煤设备_山西洗煤机_山西离心机-山西东鑫昶机械科技股份有限公司 | 无锡大型数控龙门铣加工中心,精密焊接件制造,机械设备加工-无锡嘉迅机械科技有限公司 | 装盒机|全自动封盒机|纸盒子包装机|高速装盒机定制-温州胜泰机械有限公司 | 金属剪切机,金属打包机,废钢剪切机,废铁压块机,金属压块机,废纸打包机,重废龙门剪,废钢龙门剪,箱式剪,液压剪切机-瑞顿机械装备制造江阴有限公司 | 生物发酵罐(细菌/植物/液体玻璃实验室发酵罐设备)CIP清洗罐,灭活罐「厂家」-安徽赛德齐瑞发酵罐品牌 | 日本进口东丽碳纤维材料-上海久扶新材料科技有限公司 | 生活污水处理设备-地埋式污水处理设备厂家-山东梦之洁水处理设备有限公司 | 长沙物流公司|湖南货物运输公司|长沙第三方物流公司-国联物流 湖南第三方物流专家 | 现代卓越官网-专注于pmp培训证书-pmp考试报名时间-pmp认证-项目管理pmp-ACP敏捷管理-NPDP认证 |