アナログからデジタルまで、ADC を駆動する OneOS を理解するための 1 つの記事
-
ADC装置
1.1 はじめに
ADC デバイスは、アナログをデジタルに変換するデバイス、つまり Analog-to-Digital Converter、アナログ/デジタル コンバーターです。これに対応して、デジタル量をアナログ量に変換するために使用される DAC デバイス、つまりデジタル - アナログ コンバータ、つまりデジタル/アナログ コンバータもあります。
1.2 ADCパラメータ解析
- ADCの分解能
これは、A/D コンバータが表現できる最大数、つまり ADC の桁数を指します。ADC が 10 ビット ADC の場合、分解能は 2 の 10 乗です。 、分解能は 1024 です。アナログ量が温度の場合、測定範囲は 0 ~ 100 度で、100 度を 1024 の部分に分割し、各部分を感じることができ、温度が 100/ ずつ変化したときに測定できます。 1024度。
- ADCサンプリングレート
ADC が 1 秒あたりアナログ値をデジタル値に変換する回数を指します。たとえば、10K/s は、ADC が 1 秒あたり 10K のアナログ値を収集し、アナログ値をデジタル値に変換することを意味します。
- 通路側
通常、1 つの ADC コントローラで複数のチャネルを制御しますが、複数のチャネルが必要な場合はチャネル スキャンを実行する必要があります。
- ADC変換方式
単一変換: 一度に 1 つのチャンネルのみを変換します。
連続変換: 1 つのチャンネルの変換が完了すると、すぐに次のチャンネルの変換を自動的に実行します。
スキャンモード:一度電源を入れると、自動的に複数のチャンネルを連続的に読み取ります。
- ADC の 3 つの動作モード
ブロッキングモード(クエリモード)、割り込みモード、DMAモード
- ADC デバイスのアクセスと登録
2.1 ADC デバイスへのアクセス
ユーザーが ADC デバイスにアクセスするとき、os_device_find()、os_device_open()、os_device_control()、os_device_read_nonblock()、os_device_close() などのデバイス管理層のインターフェイスを呼び出して、ADC デバイスへのアクセスを実現します。 ADC。デバイス管理層のインターフェイスは、デバイス フレームワーク層のインターフェイスを呼び出し、次にデバイス ドライバー層のインターフェイスを呼び出し、最終的に ADC ハードウェア上で関連する操作を実現します。
「os_device_control()」関数を例に挙げます。
|
関数 |
道 |
層 |
トップダウンの実行 |
os_device_control() |
ドライバー\device.c |
端末管理 (全デバイス共通の機能インターフェース) |
_adc_control() |
ドライバー\その他\adc.c |
デバイスフレームワーク層 (同様のデバイスの抽象化) |
|
stm32_adc_enabled() |
drivers\hal\st\drivers\drv_adc.c |
デバイスドライバー層 (関数インターフェースによる特定のハードウェアへのアクセス) |
2.2 ADCデバイスの登録
デバイス管理層からデバイス ドライバー層まで、ADC デバイスにアクセスするプロセスにおいて、システムはどのインターフェイスを呼び出すかをどのように決定するのでしょうか? これは、ADC デバイスの登録時に指定されたものです。デバイスの登録プロセスは、デバイス アクセスのプロセスとは逆で、登録時には、次の表に示すように、デバイス ドライバー層からデバイス管理層までが開始されます。
|
関数 |
道 |
層 |
トップダウンの実行 |
stm32_adc_probe() |
drivers\hal\st\drivers\drv_adc.c |
デバイスドライバー層 |
os_hw_adc_register() |
ドライバー\その他\adc.c |
デバイスフレームワーク層 |
|
os_device_register() |
ドライバー\device.c |
端末管理 (デバイスノードをデバイスリストに追加) |
次に、登録処理について簡単に説明する。
2.2.1 デバイスドライバー層
場所: drivers\hal\st\drivers\drv_adc.c
「stm32_adc_probe()」関数から始まる部分的なスクリーンショットを以下に示します。
- この関数の次のステートメントは、デバイスにアクセスするときに呼び出されるインターフェイス関数を決定します。
- この関数では、デバイス フレームワーク層の os_hw_adc_register() 関数が次のステートメントによって呼び出されます。
- この機能に関係する 2 つの構造
場所: drivers\bus\bus.h
2.2.2 デバイスフレームワーク層
場所: drivers\misc\adc.c
次の os_hw_adc_register() 関数は、上記のデバイス ドライバー層によって呼び出されます。
この関数では、引き続きデバイス管理層の os_device_register() インターフェイスを呼び出します。
2.2.3 デバイス管理層
場所: drivers\device.c
次の os_device_register() 関数は、前述のデバイス フレームワーク層によって呼び出されます。下の写真は部分的なスクリーンショットです。
- この関数の次のステートメントは、システムのデバイス リストにデバイス ノードを追加することを実現します。
関連する定義は次のとおりです。
①ドライバー\device.cの場所
②カーネル\インクルード\os_list.hの場所
③ os_list_add 関数の定義:
場所: kernel\include\os_list.h
④リンクリストノードの定義:
場所: kernel\include\os_list.h
- ADCデモ実行プロセス
デモファイルの場所:demos\driver\adc_test.c
上から下まで
による 左から右に実行 |
os_device_find() (デバイス.c) |
||
os_device_open() (デバイス.c) |
|||
os_device_control() (デバイス.c) |
_adc_control() (adc.c) |
stm32_adc_enabled() (drv_adc.c) |
|
os_device_read_nonblock() (デバイス.c) |
_adc_read() (adc.c) |
os_adc_read() (adc.c) |
stm32_adc_read() (drv_adc.c) |
os_device_control() (デバイス.c) |
_adc_control() (adc.c) |
stm32_adc_enabled() (drv_adc.c) |
|
os_device_close() (デバイス.c) |
道 |
① |
ドライバー\device.c |
② |
ドライバー\その他\adc.c |
|
③ |
drivers\hal\st\drivers\drv_adc.c |
adc_sample() 関数は、プロセス分析を部分的に実行します。
adc_test.c【int adc_sample(int argc, char **argv)】 |
||
関数(上から下へ実行) |
ステートメント (上から下に実行) |
関数 |
os_device_find(argv[1]) 機能:デバイス名「 argv[1] 」でデバイスを検索します。 場所: OneOS\drivers\device.c |
os_sem_wait(&dev_sem , OS_WAIT_FOREVER); |
セマフォ待機 |
for ループ |
リンクされたリスト「os_device_list」でデバイスを見つけます。 |
|
os_sem_post(&dev_sem); 開発者を返します。 |
找到则释放信号量并返回对应设备结构体(类型“os_device_t”) |
|
os_sem_post(&dev_sem); return OS_NULL; |
未找到设备则释放信号量并返回“OS_NULL” |
|
os_device_open(adc_dev); 条件:找到设备后可执行 功能:“打开”设备,可初始化设备 位置:OneOS\drivers\device.c |
os_sem_wait(&dev->sem, OS_WAIT_FOREVER); |
信号量等待 |
dev->ops->init(dev); |
初始化设备,但本测试中未进行。 涉及结构体:“os_device”“os_device_ops” |
|
os_sem_post(&dev->sem); |
释放信号量 |
|
os_plug_get("device", dev->name); return result; |
plug->ref_count++; 返回“OS_EOK” |
|
os_device_control(adc_dev, OS_ADC_CMD_ENABLE, OS_NULL); 位置:OneOS\drivers\device.c
|
switch语句 |
由输入的cmd:OS_ADC_CMD_ENABLE在switch语句中进行匹配,未匹配到对应指令 |
os_sem_wait(&dev->sem, OS_WAIT_FOREVER); |
信号量等待 |
|
dev->ops->control(dev, cmd, arg); |
进入“_adc_control()” |
|
os_sem_post(&dev->sem); return ret; |
释放信号量; 返回“_adc_control()”的返回结果 |
|
_adc_control(struct os_device *dev, int cmd, void *args) 由os_device_control()函数进入 位置:OneOS\drivers\misc\adc.c |
switch语句 |
由输入的cmd:OS_ADC_CMD_ENABLE在switch语句中进行匹配 |
adc->ops->adc_enabled(adc, OS_TRUE); return result; |
执行stm32_adc_enabled()然后返回其执行结果 |
|
stm32_adc_enabled() 由_adc_control()函数进入 位置:OneOS\drivers\hal\st\drivers\drv_adc.c |
/ |
使能设备,返回OS_EOK |
os_device_read_nonblock(adc_dev, adc_channel, &adc_databuf, sizeof(adc_databuf)); 位置:OneOS\drivers\device.c |
dev->ops->read(dev, pos, buffer, size); |
进入“_adc_read()”函数 涉及结构体:
|
return count; |
返回“_adc_read()”执行结果 |
|
_adc_read(struct os_device *dev, os_off_t pos, void *buffer, os_size_t size) |
for循环 |
|
|
return i; |
返回执行os_adc_read()的次数 |
人大毕业生盗取全校学生信息建颜值打分网站,已被刑拘 基于 NT 架构的全新 QQ Windows 版正式发布 美国将限制中国使用亚马逊、微软等提供训练 AI 模型的云服务 资金严重短缺,又一流行开源项目宣布停止功能开发 2023 年收入最高的技术岗位 LeaferJS 发布:开源、性能强悍的 2D 图形库 Visual Studio Code 1.80 发布,支持终端图片功能 Threads 注册量已破三千万,后端基于 CPython 深度“魔改” deepin 采用 Asahi Linux 适配 Apple M1 7 月数据库排行:Oracle 大涨,再度拉开比分