色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何通過IPC通信玩轉傳感器數據?

RTThread物聯網操作系統 ? 來源:RTThread物聯網操作系統 ? 作者:RTThread物聯網操作 ? 2021-01-15 13:39 ? 次閱讀

1、rt-smart的第一個應用程序,imx6ull用戶態點燈

簡介

首先糾正一下上一篇文章中,在我的倉庫中,1月11日的代碼會出現系統崩潰。原因在于我的驅動中內存物理地址映射到虛擬地址的操作有問題,我已經把這個bug解決了,如果有興趣,歡迎拉取最新的代碼。

這一篇來介紹我在rt-smart的第二個應用。這個應用將加入rt-smart與rt-thread區別之處--進程間的通信

功能主要是在用戶態讀取傳感器數據,傳感器是100ASK_imx6ull板載的ap3216c,它是采用I2C總線進行通信。

為啥這次會先對接I2C呢?因為接下來想把屏幕在rt-smart跑起來,但是屏幕的觸摸芯片采用I2C,所以就把他先跑起來。

目前屏幕已經在rt-thread上跑起來,但是在rt-smart沒有跑起來,目前在研究LCD的緩存是一個什么樣一個形式。

100ask_imx6ull驅動對接情況:

rt-threadrt-smart

GPIO√√

I2C√√

lcd√×

100ask_imx6ull的rtt倉庫:

rt-thread的倉庫:https://gitee.com/RiceChen0/imx6ull_rt_rthread

rt-smart的廠庫:https://gitee.com/RiceChen0/imx6ull_rt_smart

環境

100ask_imx6ull開發板。

兩條micro USB線。

電源。

windows電腦一臺。

I2C驅動適配

在imx6ull中,我適配的是硬件I2C,imx6ull有4組I2C接口。軟件I2C后續不會進行適配,因為在這顆芯片上,軟件I2C的必要性不大。

如果你要了解RT-Thread的I2C設備驅動框架,可以看一下我之前的文章《rt-thread驅動框架分析》-i2c驅動

在上一篇文章中《rt-smart的第一個應用程序,imx6ull用戶態點燈》講到,rt-smart不能直接使用物理地址訪問硬件,而需要采用虛擬地址。所以需要進行地址映射(rtt提供的API:rt_hw_kernel_phys_to_virt)。

首先需要查看imx6ull的芯片手冊,需要將I2C相關的物理地址找到。為了不要重復造輪子,定義了一個結構體:struct i2c_addr_config,并把4組I2C相關的地址作為一個表格。如下:

#define I2C1_SCL_MUX_BASE 0x020E00B4U

#define I2C2_SCL_MUX_BASE 0x020E00BCU

#define I2C3_SCL_MUX_BASE 0x020E00E4U

#define I2C4_SCL_MUX_BASE 0x020E00ECU

#define I2C1_SCL_CFG_BASE 0x020E0340U

#define I2C2_SCL_CFG_BASE 0x020E0348U

#define I2C3_SCL_CFG_BASE 0x020E0370U

#define I2C4_SCL_CFG_BASE 0x020E0378U

#define I2C1_SCL_INPUT_BASE 0x020E05A4U

#define I2C2_SCL_INPUT_BASE 0x020E05ACU

#define I2C3_SCL_INPUT_BASE 0x020E05B4U

#define I2C4_SCL_INPUT_BASE 0x020E05BCU

#define I2C1_SDA_MUX_BASE 0x020E00B8U

#define I2C2_SDA_MUX_BASE 0x020E00C0U

#define I2C3_SDA_MUX_BASE 0x020E00E8U

#define I2C4_SDA_MUX_BASE 0x020E00F0U

#define I2C1_SDA_CFG_BASE 0x020E0344U

#define I2C2_SDA_CFG_BASE 0x020E034CU

#define I2C3_SDA_CFG_BASE 0x020E0374U

#define I2C4_SDA_CFG_BASE 0x020E037CU

#define I2C1_SDA_INPUT_BASE 0x020E05A8U

#define I2C2_SDA_INPUT_BASE 0x020E05B0U

#define I2C3_SDA_INPUT_BASE 0x020E05B8U

#define I2C4_SDA_INPUT_BASE 0x020E05C0U

struct i2c_addr_config

{

I2C_Type *i2c;

size_t i2c_scl_mux_base;

size_t i2c_scl_config_base;

size_t i2c_scl_input_base;

size_t i2c_sda_mux_base;

size_t i2c_sda_config_base;

size_t i2c_sda_input_base

};

static struct i2c_addr_config addr_config[] =

{

{I2C1, I2C1_SCL_MUX_BASE, I2C1_SCL_CFG_BASE, I2C1_SCL_INPUT_BASE, I2C1_SDA_MUX_BASE, I2C1_SDA_CFG_BASE, I2C1_SDA_INPUT_BASE},

{I2C2, I2C2_SCL_MUX_BASE, I2C2_SCL_CFG_BASE, I2C2_SCL_INPUT_BASE, I2C2_SDA_MUX_BASE, I2C2_SDA_CFG_BASE, I2C2_SDA_INPUT_BASE},

{I2C3, I2C3_SCL_MUX_BASE, I2C3_SCL_CFG_BASE, I2C3_SCL_INPUT_BASE, I2C3_SDA_MUX_BASE, I2C3_SDA_CFG_BASE, I2C3_SDA_INPUT_BASE},

{I2C4, I2C4_SCL_MUX_BASE, I2C4_SCL_CFG_BASE, I2C4_SCL_INPUT_BASE, I2C4_SDA_MUX_BASE, I2C4_SDA_CFG_BASE, I2C4_SDA_INPUT_BASE},

};

將物理地址轉為虛擬地址,代碼如下:

for(i = 0; i 《 sizeof(addr_config) / sizeof(addr_config[0]); i++)

{

addr_config[i].i2c = (I2C_Type *)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c), 0x1000);

addr_config[i].i2c_scl_mux_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_scl_mux_base), 0x1000);

addr_config[i].i2c_scl_config_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_scl_config_base), 0x1000);

addr_config[i].i2c_scl_input_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_scl_input_base), 0x1000);

addr_config[i].i2c_sda_mux_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_sda_mux_base), 0x1000);

addr_config[i].i2c_sda_config_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_sda_config_base), 0x1000);

addr_config[i].i2c_sda_input_base = (size_t)rt_hw_kernel_phys_to_virt((void*)(addr_config[i].i2c_sda_input_base), 0x1000);

}

在imx6ull中,I2C需要的步驟,引腳初始化為I2C,然后I2C總線初始化便可以了。

目前imx6ull上,rt-thread和rt-smart都適配I2C,所以可以先看一下rt-thread的倉庫,然后再看rt-smart的倉庫,可能更加理解它的區別。

I2C的應用:

100ask_imx6ull中,板載有ap3216c傳感器,掛載在I2C1總線上。而且RT-Thread中有相應的軟件包,對接了RT-Thread的傳感器設備框架,這給我驗證代碼提供便攜。不過要在用戶態中使用該軟件包,還需要做一點操作,需要注冊該傳感器設備。

int ap3216c_test()

{

struct rt_sensor_config cfg;

cfg.intf.dev_name = “i2c1”;

cfg.mode = RT_SENSOR_MODE_POLLING;

rt_hw_ap3216c_init(“ap”, &cfg);

return RT_EOK;

}

INIT_DEVICE_EXPORT(ap3216c_test);

然后編譯燒錄,通過list_device就可以看到相對應的設備(pr_ap和li_ap),如下:

29be56fa-56f1-11eb-8b86-12bb97331649.png

RT_Thread的傳感器框架很貼心,提供了測試命令(sensor_polling li_ap),這樣就可以初步驗證傳感器是否正常工作,通過驗證,傳感器和I2C適配都能正常工作:

29dbdc34-56f1-11eb-8b86-12bb97331649.png

上面的驗證都是在內核態中測試的,而這篇文章的目的是要在用戶態中讀取傳感器數據,為了進一步了解rt-smart和RT-Thread的區別,我這個應用采用進程通信(IPC)做了例子,該例子將上一篇文章例子結合起來:

有兩個進程, 進程1和進程2

進程1,通過接收等待進程2讀取的傳感器數據是否超標的狀態,來進行閃燈。

進程2,通過讀取ap3216c傳感器光強度數據,判斷是否超過50lux,如果超過則通知進程1進行閃燈提示。

IPC通信,詳情可以查看官網:https://www.rt-thread.org/document/site/rt-smart/architecture/architecture/。

進程1,等待接收通道發來的“warning”信息,然后進行閃燈操作:

int main(int argc, char **argv)

{

struct rt_device_pin_mode pin_mode;

struct rt_device_pin_status pin_status;

int server_ch;

int shmid;

struct rt_channel_msg msg_text;

char *str;

printf(“RiceChen rt-smart first app

”);

/* create the IPC channel for ‘server’ */

server_ch = rt_channel_open(“server”, O_CREAT);

if (server_ch == -1) {

printf(“Error: rt_channel_open: fail to create the IPC channel for server!

”);

return -1;

}

printf(“

server: wait on the IPC channel: %d

”, server_ch);

pin_dev = rt_device_find(“pin”);

if(pin_dev == RT_NULL)

{

printf(“not find pin device

”);

return RT_ERROR;

}

rt_device_open(pin_dev, RT_DEVICE_OFLAG_RDWR);

pin_mode.pin = LED_PIN;

pin_mode.mode = 0; //OUTPUT

rt_device_control(pin_dev, 0, (void *)&pin_mode);

pin_status.pin = LED_PIN;

while(1)

{

rt_channel_recv(server_ch, &msg_text); //接收通道信息

shmid = (int)msg_text.u.d;

if (shmid 《 0 || ?。╯tr = (char *)lwp_shmat(shmid, NULL)))

{

msg_text.u.d = (void *)-1;

printf(“server: receive an invalid shared-memory page.

”);

rt_channel_reply(server_ch, &msg_text); /* send back -1 */

continue;

}

if(strcmp(str, “warning”) == 0) //判斷是否接收到“warning”信息

{

printf(“light warning.

”);

pin_status.status = 1;

rt_device_write(pin_dev, 0, (void *)&pin_status, sizeof(pin_status));

rt_thread_mdelay(200);

pin_status.status = 0;

rt_device_write(pin_dev, 0, (void *)&pin_status, sizeof(pin_status));

rt_thread_mdelay(200);

pin_status.status = 1;

rt_device_write(pin_dev, 0, (void *)&pin_status, sizeof(pin_status));

rt_thread_mdelay(200);

pin_status.status = 0;

rt_device_write(pin_dev, 0, (void *)&pin_status, sizeof(pin_status));

rt_thread_mdelay(200);

}

lwp_shmdt(str);

msg_text.type = RT_CHANNEL_RAW;

msg_text.u.d = (void *)1;

rt_channel_reply(server_ch, &msg_text);

}

return 0;

}

進程2,間隔兩面讀取一次傳感器光強度數據,然后判斷是否操作50lux,超過則通過通道通知進程1進行閃燈:

int main(int argc, char **argv)

{

rt_device_t ap3216c_dev;

struct rt_sensor_data sensor_data;

int res;

int server_ch;

char warning_msg[256] = { 0 };

size_t len = 0;

/* channel messages to send and return back */

struct rt_channel_msg ch_msg, ch_msg_ret;

printf(“RiceChen rt-smart second app

”);

/* open the IPC channel created by ‘pong’ */

server_ch = rt_channel_open(“server”, 0);

if (server_ch == -1)

{

printf(“Error: rt_channel_open: could not find the ‘server’ channel!

”);

return -1;

}

ap3216c_dev = rt_device_find(SENSOR_NAME);

if (ap3216c_dev == RT_NULL)

{

rt_kprintf(“Can‘t find device:%s”, SENSOR_NAME);

return -1;

}

if (rt_device_open(ap3216c_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)

{

rt_kprintf(“open device failed!”);

return -1;

}

rt_device_control(ap3216c_dev, RT_SENSOR_CTRL_SET_ODR, (void *)100);

while(1)

{

res = rt_device_read(ap3216c_dev, 0, &sensor_data, 1); //讀取傳感器數值

if (res != 1)

{

rt_kprintf(“read data failed!size is %d

”, res);

}

else

{

rt_kprintf(“light:%5d lux, timestamp:%5d

”, sensor_data.light, sensor_data.timestamp);

}

if(sensor_data.light 》 50) //判斷閾值

{

ch_msg.type = RT_CHANNEL_RAW;

snprintf(warning_msg, 255, “%s”, “warning”);

len = strlen(warning_msg) + 1;

warning_msg[len] = ’‘;

int shmid = prepare_data(warning_msg, len);

if (shmid 《 0)

{

printf(“clent: fail to prepare the clent message.

”);

continue;

}

ch_msg.u.d = (void *)shmid;

rt_channel_send_recv(server_ch, &ch_msg, &ch_msg_ret); //發送警報信息

lwp_shmrm(shmid);

}

rt_thread_mdelay(2000);

}

rt_device_close(ap3216c_dev);

rt_channel_close(server_ch);

return 0;

}

演示

原文標題:rt-smart用戶態通過IPC通信玩轉傳感器數據

文章出處:【微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 傳感器
    +關注

    關注

    2550

    文章

    51071

    瀏覽量

    753343
  • 通信
    +關注

    關注

    18

    文章

    6030

    瀏覽量

    135975
  • 操作系統
    +關注

    關注

    37

    文章

    6818

    瀏覽量

    123320
  • IPC
    IPC
    +關注

    關注

    3

    文章

    347

    瀏覽量

    51910

原文標題:rt-smart用戶態通過IPC通信玩轉傳感器數據

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    ADS1232對差阻式傳感器進行測量數據跳動大是什么原因導致的?

    使用的是12V輸入,通過7805轉換為5V,再通過LM117-3.3轉換為2路3.3V,分別給模擬電路和數字電路供電,通過2.5V基準產生2.5電壓,再通過運放設計成恒流電路測量差阻
    發表于 11-27 06:20

    ipc協議在物聯網中的應用

    聯網概述 物聯網是一個由互聯網、傳統電信網、傳感器網絡等多種網絡組成的網絡,它允許物體與物體、物體與人、人與人之間的智能互聯。物聯網的核心在于數據的收集、傳輸、處理和應用,而通信協議則是實現這些功能的基礎。 2.
    的頭像 發表于 11-15 14:19 ?316次閱讀

    實現MCU與傳感器通信方式

    在現代電子系統中,微控制單元(MCU)與傳感器通信是實現智能控制和數據采集的基礎。隨著技術的發展,MCU與傳感器之間的
    的頭像 發表于 11-01 13:43 ?351次閱讀

    傳感器數據怎么傳到云平臺

    傳感器數據傳到云平臺,通??梢?b class='flag-5'>通過以下幾種方式實現: 1. 直接連接 網絡接口 :傳感器可以通過以太網、Wi-Fi等網絡接口直接連接到云服
    的頭像 發表于 09-07 10:59 ?1860次閱讀

    車載傳感器網絡是什么意思啊

    車載傳感器網絡(Vehicle Sensor Networks,VSN)是指在車輛上部署的傳感器網絡,用于收集車輛運行狀態、環境信息、交通狀況等數據,并通過無線
    的頭像 發表于 09-07 09:32 ?446次閱讀

    lidar傳感器和激光測距傳感器的區別

    基于激光雷達技術的傳感器,它通過發射激光脈沖并接收反射回來的激光信號來測量距離。LiDAR傳感器可以同時測量多個點的距離,從而生成三維空間的點云數據。 激光測距
    的頭像 發表于 08-29 15:56 ?533次閱讀

    水位傳感器怎么測好壞

    傳感器的工作原理主要是通過檢測液體的導電性或壓力變化來實現水位的測量。根據檢測方式的不同,水位傳感器可以分為以下幾種類型: 電阻式水位傳感器通過
    的頭像 發表于 06-19 10:38 ?1671次閱讀

    傳感器數據采集平臺是什么

    傳感器數據采集平臺是一種系統,用于收集來自各種傳感器數據顯示和處理。這些傳感器可以監測環境條件、物理參數、生物特征等眾多類型的信息。
    的頭像 發表于 06-13 09:26 ?600次閱讀

    請問傳感器怎么和STM32實現modbus rtu通信?

    第一次接觸Modbus,傳感器是采用Modbus協議的485信號,我用STM32做主機,想把傳感器采集的數據顯示到STM32觸摸屏上,要怎么實現modbus通信啊,有木有具體的例程可以
    發表于 05-17 08:57

    求助,關于STM8L101和BMP180傳感器通信的疑問求解

    STM8L101和BMP180傳感器通信,我加上一段濾波算法之后,用熱風吹傳感器,返回數據異常,去掉之后吹就無異常,不管濾波處理還是不處理180的
    發表于 05-14 07:26

    指紋傳感器的定義 指紋傳感器的應用

    指紋傳感器的定義 指紋傳感器的應用? 指紋傳感器是一種生物識別技術,通過檢測和分析人體指紋特征來驗證用戶身份。它基于指紋獨特性和穩定性的基本原理,
    的頭像 發表于 03-05 17:35 ?3152次閱讀

    HarmonyOS跨進程通信IPC與RPC通信開發

    一、IPC與RPC通信概述 基本概念 IPC(Inter-Process Communication)與RPC(Remote Procedure Call)用于實現跨進程通信,不同的是
    的頭像 發表于 02-02 17:47 ?1281次閱讀
    HarmonyOS跨進程<b class='flag-5'>通信</b>—<b class='flag-5'>IPC</b>與RPC<b class='flag-5'>通信</b>開發

    如何通過仿真動圖理解各種傳感器的原理呢?

    如何通過仿真動圖理解各種傳感器的原理呢?
    發表于 01-15 10:39 ?528次閱讀
    如何<b class='flag-5'>通過</b>仿真動圖理解各種<b class='flag-5'>傳感器</b>的原理呢?

    stm32和傳感器進行通信,為什么返回的數據基本是0呢?

    本人使用的是stm32和傳感器進行通信,再設置好SPI的基礎設置后,去讀取x軸的陀螺儀角速度,為什么返回的數據基本是0呢?
    發表于 01-02 06:10

    傳感器抽象框架有哪些

    傳感器抽象框架是一種用于開發和管理傳感器網絡的軟件架構。它提供了一種抽象和整合的方式來處理傳感器節點、傳感器數據
    的頭像 發表于 12-28 14:08 ?668次閱讀
    主站蜘蛛池模板: 国产精品一区二区在线观看| 亚洲不卡视频在线观看| 老师湿乎乎两半嫩| 后入式啪gif动态图| 国产精品青青草原app大全| 成人免费视频在线观看| YELLOW免费观看2019| 99九九免费热在线精品| 97精品一区二区视频在线观看| 在线国内自拍精品视频| 樱花草动漫www| 中文字幕在线久热精品| 最近韩国HD免费观看国语| 征服丝袜旗袍人妻| 综合色就爱涩涩涩综合婷婷| 做a爱片的全过程| 91国内精品久久久久免费影院| 2012中文字幕在线动漫电影| 99精品观看| 菠萝视频高清版在线观看| 岛国大片在线播放免费| 国产精品18久久久久网站| 国产亚洲精品久久77777| 国产一级特黄a大片99| 精品伊人久久| 麻美ゆま夫の目の前で犯| 嫩草影院在线观看精品视频| 日本久久高清视频| 微福利92合集| 亚洲蜜桃AV永久无码精品放毛片| 一本到道免费线观看| 66美女人体| 成人网站国产在线视频内射视频 | 亚洲欧美成人在线| 一级大乳奶| 99精品欧美一区二区三区美图| 成电影人免费网站| 国产精品视频在线自在线| 久久99精品AV99果冻| 美女搞鸡网站| 色狼亚洲色图|