@mytechtoday/augment-extensions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
- package/augment-extensions/coding-standards/c/LICENSE +22 -0
- package/augment-extensions/coding-standards/c/README.md +167 -0
- package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
- package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
- package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
- package/augment-extensions/coding-standards/c/config/schema.json +244 -0
- package/augment-extensions/coding-standards/c/docs/API.md +613 -0
- package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
- package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
- package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
- package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
- package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
- package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
- package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
- package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
- package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
- package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
- package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
- package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
- package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
- package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
- package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
- package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
- package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
- package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
- package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
- package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
- package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
- package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
- package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
- package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
- package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
- package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
- package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
- package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
- package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
- package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
- package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
- package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
- package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
- package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
- package/augment-extensions/coding-standards/c/module.json +149 -0
- package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
- package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
- package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
- package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
- package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
- package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
- package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
- package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
- package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
- package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
- package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
- package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
- package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
- package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
- package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
- package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
- package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
- package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
- package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
- package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
- package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
- package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
- package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
- package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
- package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
- package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
- package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
- package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
- package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
- package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
- package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
- package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
- package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
- package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
- package/augment-extensions/coding-standards/go/README.md +200 -0
- package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
- package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
- package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
- package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
- package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
- package/augment-extensions/coding-standards/go/config/schema.json +110 -0
- package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
- package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
- package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
- package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
- package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
- package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
- package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
- package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
- package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
- package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
- package/augment-extensions/coding-standards/go/module.json +139 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
- package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
- package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
- package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
- package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
- package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
- package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
- package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
- package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
- package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
- package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
- package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
- package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
- package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
- package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
- package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
- package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
- package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
- package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
- package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
- package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
- package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
- package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
- package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
- package/cli/dist/analysis/ast-parser.d.ts +47 -0
- package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
- package/cli/dist/analysis/ast-parser.js +161 -0
- package/cli/dist/analysis/ast-parser.js.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.js +189 -0
- package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.js +237 -0
- package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
- package/cli/dist/analysis/index.d.ts +9 -0
- package/cli/dist/analysis/index.d.ts.map +1 -0
- package/cli/dist/analysis/index.js +25 -0
- package/cli/dist/analysis/index.js.map +1 -0
- package/cli/dist/analysis/security-scanner.d.ts +11 -0
- package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
- package/cli/dist/analysis/security-scanner.js +294 -0
- package/cli/dist/analysis/security-scanner.js.map +1 -0
- package/cli/dist/analysis/types.d.ts +151 -0
- package/cli/dist/analysis/types.d.ts.map +1 -0
- package/cli/dist/analysis/types.js +6 -0
- package/cli/dist/analysis/types.js.map +1 -0
- package/cli/dist/cli.js +24 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/code-analysis.d.ts +11 -0
- package/cli/dist/commands/code-analysis.d.ts.map +1 -0
- package/cli/dist/commands/code-analysis.js +412 -0
- package/cli/dist/commands/code-analysis.js.map +1 -0
- package/modules.md +99 -3
- package/package.json +14 -2
- package/cli/dist/commands/agent.d.ts +0 -37
- package/cli/dist/commands/agent.d.ts.map +0 -1
- package/cli/dist/commands/agent.js +0 -222
- package/cli/dist/commands/agent.js.map +0 -1
- package/cli/dist/commands/beads.d.ts +0 -64
- package/cli/dist/commands/beads.d.ts.map +0 -1
- package/cli/dist/commands/beads.js +0 -377
- package/cli/dist/commands/beads.js.map +0 -1
- package/cli/dist/commands/change.d.ts +0 -54
- package/cli/dist/commands/change.d.ts.map +0 -1
- package/cli/dist/commands/change.js +0 -243
- package/cli/dist/commands/change.js.map +0 -1
- package/cli/dist/commands/clean.d.ts +0 -15
- package/cli/dist/commands/clean.d.ts.map +0 -1
- package/cli/dist/commands/clean.js +0 -63
- package/cli/dist/commands/clean.js.map +0 -1
- package/cli/dist/commands/clone.d.ts +0 -15
- package/cli/dist/commands/clone.d.ts.map +0 -1
- package/cli/dist/commands/clone.js +0 -49
- package/cli/dist/commands/clone.js.map +0 -1
- package/cli/dist/commands/config.d.ts +0 -33
- package/cli/dist/commands/config.d.ts.map +0 -1
- package/cli/dist/commands/config.js +0 -166
- package/cli/dist/commands/config.js.map +0 -1
- package/cli/dist/commands/context.d.ts +0 -38
- package/cli/dist/commands/context.d.ts.map +0 -1
- package/cli/dist/commands/context.js +0 -205
- package/cli/dist/commands/context.js.map +0 -1
- package/cli/dist/commands/create.d.ts +0 -18
- package/cli/dist/commands/create.d.ts.map +0 -1
- package/cli/dist/commands/create.js +0 -178
- package/cli/dist/commands/create.js.map +0 -1
- package/cli/dist/commands/diff.d.ts +0 -19
- package/cli/dist/commands/diff.d.ts.map +0 -1
- package/cli/dist/commands/diff.js +0 -104
- package/cli/dist/commands/diff.js.map +0 -1
- package/cli/dist/commands/doctor.d.ts +0 -14
- package/cli/dist/commands/doctor.d.ts.map +0 -1
- package/cli/dist/commands/doctor.js +0 -62
- package/cli/dist/commands/doctor.js.map +0 -1
- package/cli/dist/commands/export.d.ts +0 -28
- package/cli/dist/commands/export.d.ts.map +0 -1
- package/cli/dist/commands/export.js +0 -135
- package/cli/dist/commands/export.js.map +0 -1
- package/cli/dist/commands/import.d.ts +0 -23
- package/cli/dist/commands/import.d.ts.map +0 -1
- package/cli/dist/commands/import.js +0 -118
- package/cli/dist/commands/import.js.map +0 -1
- package/cli/dist/commands/prompt.d.ts +0 -45
- package/cli/dist/commands/prompt.d.ts.map +0 -1
- package/cli/dist/commands/prompt.js +0 -223
- package/cli/dist/commands/prompt.js.map +0 -1
- package/cli/dist/commands/spec.d.ts +0 -57
- package/cli/dist/commands/spec.d.ts.map +0 -1
- package/cli/dist/commands/spec.js +0 -279
- package/cli/dist/commands/spec.js.map +0 -1
- package/cli/dist/commands/stats.d.ts +0 -18
- package/cli/dist/commands/stats.d.ts.map +0 -1
- package/cli/dist/commands/stats.js +0 -85
- package/cli/dist/commands/stats.js.map +0 -1
- package/cli/dist/commands/task.d.ts +0 -65
- package/cli/dist/commands/task.d.ts.map +0 -1
- package/cli/dist/commands/task.js +0 -282
- package/cli/dist/commands/task.js.map +0 -1
- package/cli/dist/commands/template.d.ts +0 -17
- package/cli/dist/commands/template.d.ts.map +0 -1
- package/cli/dist/commands/template.js +0 -55
- package/cli/dist/commands/template.js.map +0 -1
- package/cli/dist/utils/agent-config.d.ts +0 -129
- package/cli/dist/utils/agent-config.d.ts.map +0 -1
- package/cli/dist/utils/agent-config.js +0 -297
- package/cli/dist/utils/agent-config.js.map +0 -1
- package/cli/dist/utils/beads-graph.d.ts +0 -17
- package/cli/dist/utils/beads-graph.d.ts.map +0 -1
- package/cli/dist/utils/beads-graph.js +0 -150
- package/cli/dist/utils/beads-graph.js.map +0 -1
- package/cli/dist/utils/beads-integration.d.ts +0 -112
- package/cli/dist/utils/beads-integration.d.ts.map +0 -1
- package/cli/dist/utils/beads-integration.js +0 -312
- package/cli/dist/utils/beads-integration.js.map +0 -1
- package/cli/dist/utils/beads-reporter.d.ts +0 -17
- package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
- package/cli/dist/utils/beads-reporter.js +0 -160
- package/cli/dist/utils/beads-reporter.js.map +0 -1
- package/cli/dist/utils/cache-manager.d.ts +0 -55
- package/cli/dist/utils/cache-manager.d.ts.map +0 -1
- package/cli/dist/utils/cache-manager.js +0 -150
- package/cli/dist/utils/cache-manager.js.map +0 -1
- package/cli/dist/utils/change-manager.d.ts +0 -70
- package/cli/dist/utils/change-manager.d.ts.map +0 -1
- package/cli/dist/utils/change-manager.js +0 -412
- package/cli/dist/utils/change-manager.js.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.js +0 -77
- package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
- package/cli/dist/utils/context-manager.d.ts +0 -96
- package/cli/dist/utils/context-manager.d.ts.map +0 -1
- package/cli/dist/utils/context-manager.js +0 -258
- package/cli/dist/utils/context-manager.js.map +0 -1
- package/cli/dist/utils/diff-engine.d.ts +0 -78
- package/cli/dist/utils/diff-engine.d.ts.map +0 -1
- package/cli/dist/utils/diff-engine.js +0 -233
- package/cli/dist/utils/diff-engine.js.map +0 -1
- package/cli/dist/utils/export-system.d.ts +0 -101
- package/cli/dist/utils/export-system.d.ts.map +0 -1
- package/cli/dist/utils/export-system.js +0 -289
- package/cli/dist/utils/export-system.js.map +0 -1
- package/cli/dist/utils/health-checker.d.ts +0 -66
- package/cli/dist/utils/health-checker.d.ts.map +0 -1
- package/cli/dist/utils/health-checker.js +0 -285
- package/cli/dist/utils/health-checker.js.map +0 -1
- package/cli/dist/utils/import-system.d.ts +0 -74
- package/cli/dist/utils/import-system.d.ts.map +0 -1
- package/cli/dist/utils/import-system.js +0 -317
- package/cli/dist/utils/import-system.js.map +0 -1
- package/cli/dist/utils/module-cloner.d.ts +0 -40
- package/cli/dist/utils/module-cloner.d.ts.map +0 -1
- package/cli/dist/utils/module-cloner.js +0 -136
- package/cli/dist/utils/module-cloner.js.map +0 -1
- package/cli/dist/utils/prompt-manager.d.ts +0 -90
- package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
- package/cli/dist/utils/prompt-manager.js +0 -302
- package/cli/dist/utils/prompt-manager.js.map +0 -1
- package/cli/dist/utils/spec-manager.d.ts +0 -65
- package/cli/dist/utils/spec-manager.d.ts.map +0 -1
- package/cli/dist/utils/spec-manager.js +0 -329
- package/cli/dist/utils/spec-manager.js.map +0 -1
- package/cli/dist/utils/stats-collector.d.ts +0 -74
- package/cli/dist/utils/stats-collector.d.ts.map +0 -1
- package/cli/dist/utils/stats-collector.js +0 -164
- package/cli/dist/utils/stats-collector.js.map +0 -1
- package/cli/dist/utils/template-engine.d.ts +0 -47
- package/cli/dist/utils/template-engine.d.ts.map +0 -1
- package/cli/dist/utils/template-engine.js +0 -204
- package/cli/dist/utils/template-engine.js.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file uart-communication.c
|
|
3
|
+
* @brief Example demonstrating UART communication for embedded systems
|
|
4
|
+
*
|
|
5
|
+
* This example shows:
|
|
6
|
+
* - UART initialization and configuration
|
|
7
|
+
* - Interrupt-driven UART transmission
|
|
8
|
+
* - Circular buffer for received data
|
|
9
|
+
* - Hardware abstraction layer
|
|
10
|
+
* - Error handling
|
|
11
|
+
*
|
|
12
|
+
* Target: Generic ARM Cortex-M microcontroller
|
|
13
|
+
* Note: This is a demonstration. Actual addresses depend on your hardware.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include <stdint.h>
|
|
17
|
+
#include <stdbool.h>
|
|
18
|
+
#include <string.h>
|
|
19
|
+
|
|
20
|
+
// UART register addresses (example for STM32-like MCU)
|
|
21
|
+
#define USART1_BASE 0x40013800UL
|
|
22
|
+
#define USART1_SR (*(volatile uint32_t *)(USART1_BASE + 0x00))
|
|
23
|
+
#define USART1_DR (*(volatile uint32_t *)(USART1_BASE + 0x04))
|
|
24
|
+
#define USART1_BRR (*(volatile uint32_t *)(USART1_BASE + 0x08))
|
|
25
|
+
#define USART1_CR1 (*(volatile uint32_t *)(USART1_BASE + 0x0C))
|
|
26
|
+
|
|
27
|
+
// UART status register bits
|
|
28
|
+
#define USART_SR_TXE (1UL << 7) // Transmit data register empty
|
|
29
|
+
#define USART_SR_RXNE (1UL << 5) // Read data register not empty
|
|
30
|
+
#define USART_SR_ORE (1UL << 3) // Overrun error
|
|
31
|
+
#define USART_SR_FE (1UL << 1) // Framing error
|
|
32
|
+
|
|
33
|
+
// UART control register bits
|
|
34
|
+
#define USART_CR1_UE (1UL << 13) // USART enable
|
|
35
|
+
#define USART_CR1_TE (1UL << 3) // Transmitter enable
|
|
36
|
+
#define USART_CR1_RE (1UL << 2) // Receiver enable
|
|
37
|
+
#define USART_CR1_RXNEIE (1UL << 5) // RXNE interrupt enable
|
|
38
|
+
|
|
39
|
+
// Circular buffer for received data
|
|
40
|
+
#define RX_BUFFER_SIZE 256
|
|
41
|
+
|
|
42
|
+
typedef struct {
|
|
43
|
+
uint8_t buffer[RX_BUFFER_SIZE];
|
|
44
|
+
volatile uint16_t head;
|
|
45
|
+
volatile uint16_t tail;
|
|
46
|
+
} circular_buffer_t;
|
|
47
|
+
|
|
48
|
+
static circular_buffer_t rx_buffer = {0};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @brief Initialize circular buffer
|
|
52
|
+
* @param cb Pointer to circular buffer
|
|
53
|
+
*/
|
|
54
|
+
void buffer_init(circular_buffer_t *cb) {
|
|
55
|
+
cb->head = 0;
|
|
56
|
+
cb->tail = 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @brief Write byte to circular buffer
|
|
61
|
+
* @param cb Pointer to circular buffer
|
|
62
|
+
* @param data Byte to write
|
|
63
|
+
* @return true if successful, false if buffer full
|
|
64
|
+
*/
|
|
65
|
+
bool buffer_write(circular_buffer_t *cb, uint8_t data) {
|
|
66
|
+
uint16_t next_head = (cb->head + 1) % RX_BUFFER_SIZE;
|
|
67
|
+
|
|
68
|
+
if (next_head == cb->tail) {
|
|
69
|
+
return false; // Buffer full
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
cb->buffer[cb->head] = data;
|
|
73
|
+
cb->head = next_head;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @brief Read byte from circular buffer
|
|
79
|
+
* @param cb Pointer to circular buffer
|
|
80
|
+
* @param data Pointer to store read byte
|
|
81
|
+
* @return true if successful, false if buffer empty
|
|
82
|
+
*/
|
|
83
|
+
bool buffer_read(circular_buffer_t *cb, uint8_t *data) {
|
|
84
|
+
if (cb->head == cb->tail) {
|
|
85
|
+
return false; // Buffer empty
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
*data = cb->buffer[cb->tail];
|
|
89
|
+
cb->tail = (cb->tail + 1) % RX_BUFFER_SIZE;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @brief Get number of bytes available in buffer
|
|
95
|
+
* @param cb Pointer to circular buffer
|
|
96
|
+
* @return Number of bytes available
|
|
97
|
+
*/
|
|
98
|
+
uint16_t buffer_available(const circular_buffer_t *cb) {
|
|
99
|
+
return (cb->head - cb->tail + RX_BUFFER_SIZE) % RX_BUFFER_SIZE;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @brief Initialize UART
|
|
104
|
+
* @param baudrate Desired baud rate
|
|
105
|
+
* @param sysclk System clock frequency in Hz
|
|
106
|
+
*/
|
|
107
|
+
void uart_init(uint32_t baudrate, uint32_t sysclk) {
|
|
108
|
+
// Disable UART during configuration
|
|
109
|
+
USART1_CR1 &= ~USART_CR1_UE;
|
|
110
|
+
|
|
111
|
+
// Configure baud rate
|
|
112
|
+
// BRR = sysclk / baudrate
|
|
113
|
+
USART1_BRR = sysclk / baudrate;
|
|
114
|
+
|
|
115
|
+
// Enable UART, transmitter, receiver, and RX interrupt
|
|
116
|
+
USART1_CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
|
|
117
|
+
|
|
118
|
+
// Initialize RX buffer
|
|
119
|
+
buffer_init(&rx_buffer);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @brief UART interrupt service routine
|
|
124
|
+
*/
|
|
125
|
+
void USART1_IRQHandler(void) {
|
|
126
|
+
// Check for receive interrupt
|
|
127
|
+
if (USART1_SR & USART_SR_RXNE) {
|
|
128
|
+
uint8_t data = (uint8_t)(USART1_DR & 0xFF);
|
|
129
|
+
|
|
130
|
+
// Store in circular buffer
|
|
131
|
+
if (!buffer_write(&rx_buffer, data)) {
|
|
132
|
+
// Buffer overflow - data lost
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Check for errors
|
|
137
|
+
if (USART1_SR & (USART_SR_ORE | USART_SR_FE)) {
|
|
138
|
+
// Clear error by reading DR
|
|
139
|
+
(void)USART1_DR;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @brief Send single byte via UART
|
|
145
|
+
* @param data Byte to send
|
|
146
|
+
*/
|
|
147
|
+
void uart_send_byte(uint8_t data) {
|
|
148
|
+
// Wait for transmit register to be empty
|
|
149
|
+
while (!(USART1_SR & USART_SR_TXE)) {
|
|
150
|
+
// Wait
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
USART1_DR = data;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @brief Send string via UART
|
|
158
|
+
* @param str Null-terminated string to send
|
|
159
|
+
*/
|
|
160
|
+
void uart_send_string(const char *str) {
|
|
161
|
+
while (*str) {
|
|
162
|
+
uart_send_byte((uint8_t)*str++);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @brief Receive byte from UART (non-blocking)
|
|
168
|
+
* @param data Pointer to store received byte
|
|
169
|
+
* @return true if byte received, false if no data available
|
|
170
|
+
*/
|
|
171
|
+
bool uart_receive_byte(uint8_t *data) {
|
|
172
|
+
return buffer_read(&rx_buffer, data);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @brief Check if data is available
|
|
177
|
+
* @return Number of bytes available
|
|
178
|
+
*/
|
|
179
|
+
uint16_t uart_available(void) {
|
|
180
|
+
return buffer_available(&rx_buffer);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @brief Example: Echo received characters
|
|
185
|
+
*/
|
|
186
|
+
void uart_echo_example(void) {
|
|
187
|
+
uint8_t data;
|
|
188
|
+
|
|
189
|
+
while (1) {
|
|
190
|
+
if (uart_receive_byte(&data)) {
|
|
191
|
+
// Echo back received character
|
|
192
|
+
uart_send_byte(data);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @brief Main function
|
|
199
|
+
*/
|
|
200
|
+
int main(void) {
|
|
201
|
+
// Initialize UART (115200 baud, 72MHz system clock)
|
|
202
|
+
uart_init(115200, 72000000);
|
|
203
|
+
|
|
204
|
+
// Send startup message
|
|
205
|
+
uart_send_string("UART Example Started\r\n");
|
|
206
|
+
|
|
207
|
+
// Run echo example
|
|
208
|
+
uart_echo_example();
|
|
209
|
+
|
|
210
|
+
return 0; // Never reached
|
|
211
|
+
}
|
|
212
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Makefile for Linux Kernel Modules
|
|
2
|
+
# Kbuild system for building kernel modules
|
|
3
|
+
|
|
4
|
+
# Module names
|
|
5
|
+
obj-m += simple-module.o
|
|
6
|
+
obj-m += char-device.o
|
|
7
|
+
obj-m += proc-file.o
|
|
8
|
+
|
|
9
|
+
# Kernel build directory
|
|
10
|
+
KDIR ?= /lib/modules/$(shell uname -r)/build
|
|
11
|
+
|
|
12
|
+
# Current directory
|
|
13
|
+
PWD := $(shell pwd)
|
|
14
|
+
|
|
15
|
+
# Default target
|
|
16
|
+
all:
|
|
17
|
+
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
|
18
|
+
|
|
19
|
+
# Clean target
|
|
20
|
+
clean:
|
|
21
|
+
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
|
22
|
+
|
|
23
|
+
# Install modules (requires root)
|
|
24
|
+
install:
|
|
25
|
+
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
|
|
26
|
+
|
|
27
|
+
# Help target
|
|
28
|
+
help:
|
|
29
|
+
@echo "Kernel Module Makefile"
|
|
30
|
+
@echo "======================"
|
|
31
|
+
@echo "Targets:"
|
|
32
|
+
@echo " all - Build all kernel modules (default)"
|
|
33
|
+
@echo " clean - Remove build artifacts"
|
|
34
|
+
@echo " install - Install modules (requires root)"
|
|
35
|
+
@echo " load - Load all modules (requires root)"
|
|
36
|
+
@echo " unload - Unload all modules (requires root)"
|
|
37
|
+
@echo ""
|
|
38
|
+
@echo "Individual module targets:"
|
|
39
|
+
@echo " load-simple - Load simple-module"
|
|
40
|
+
@echo " load-chardev - Load char-device"
|
|
41
|
+
@echo " load-proc - Load proc-file"
|
|
42
|
+
|
|
43
|
+
# Load modules
|
|
44
|
+
load: all
|
|
45
|
+
sudo insmod simple-module.ko
|
|
46
|
+
sudo insmod char-device.ko
|
|
47
|
+
sudo insmod proc-file.ko
|
|
48
|
+
@echo "Modules loaded. Check with: lsmod | grep -E 'simple|char|proc'"
|
|
49
|
+
|
|
50
|
+
# Unload modules
|
|
51
|
+
unload:
|
|
52
|
+
-sudo rmmod proc-file
|
|
53
|
+
-sudo rmmod char-device
|
|
54
|
+
-sudo rmmod simple-module
|
|
55
|
+
@echo "Modules unloaded"
|
|
56
|
+
|
|
57
|
+
# Individual module load targets
|
|
58
|
+
load-simple: simple-module.ko
|
|
59
|
+
sudo insmod simple-module.ko
|
|
60
|
+
@echo "simple-module loaded"
|
|
61
|
+
|
|
62
|
+
load-chardev: char-device.ko
|
|
63
|
+
sudo insmod char-device.ko
|
|
64
|
+
@echo "char-device loaded. Device: /dev/chardev0"
|
|
65
|
+
|
|
66
|
+
load-proc: proc-file.ko
|
|
67
|
+
sudo insmod proc-file.ko
|
|
68
|
+
@echo "proc-file loaded. Interface: /proc/example_proc"
|
|
69
|
+
|
|
70
|
+
# Test targets
|
|
71
|
+
test-chardev:
|
|
72
|
+
@echo "Testing character device..."
|
|
73
|
+
@echo "test data" | sudo tee /dev/chardev0
|
|
74
|
+
@sudo cat /dev/chardev0
|
|
75
|
+
|
|
76
|
+
test-proc:
|
|
77
|
+
@echo "Testing proc file..."
|
|
78
|
+
@echo "test value" | sudo tee /proc/example_proc
|
|
79
|
+
@cat /proc/example_proc
|
|
80
|
+
|
|
81
|
+
.PHONY: all clean install help load unload load-simple load-chardev load-proc test-chardev test-proc
|
|
82
|
+
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Linux Kernel Development Examples
|
|
2
|
+
|
|
3
|
+
This directory contains Linux kernel module examples demonstrating kernel programming best practices.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### 1. simple-module.c
|
|
8
|
+
Basic kernel module structure:
|
|
9
|
+
- Module initialization and cleanup
|
|
10
|
+
- Module parameters
|
|
11
|
+
- Kernel logging with printk
|
|
12
|
+
- Module metadata
|
|
13
|
+
- Error handling
|
|
14
|
+
|
|
15
|
+
**Key Concepts:**
|
|
16
|
+
- Use `module_init()` and `module_exit()`
|
|
17
|
+
- Always check return values
|
|
18
|
+
- Clean up resources in exit function
|
|
19
|
+
- Use appropriate log levels
|
|
20
|
+
|
|
21
|
+
### 2. char-device.c
|
|
22
|
+
Character device driver:
|
|
23
|
+
- Device registration with cdev
|
|
24
|
+
- File operations (open, read, write, release)
|
|
25
|
+
- Device number allocation
|
|
26
|
+
- User-kernel space data transfer
|
|
27
|
+
- Device class creation
|
|
28
|
+
|
|
29
|
+
**Key Concepts:**
|
|
30
|
+
- Use `copy_to_user()` and `copy_from_user()`
|
|
31
|
+
- Proper error handling and cleanup
|
|
32
|
+
- Device file creation in /dev
|
|
33
|
+
- Resource management
|
|
34
|
+
|
|
35
|
+
### 3. proc-file.c
|
|
36
|
+
/proc filesystem interface:
|
|
37
|
+
- Creating /proc entries
|
|
38
|
+
- Sequence file interface
|
|
39
|
+
- Read/write operations
|
|
40
|
+
- Kernel-user communication
|
|
41
|
+
|
|
42
|
+
**Key Concepts:**
|
|
43
|
+
- Use seq_file for /proc entries
|
|
44
|
+
- Handle user input safely
|
|
45
|
+
- Proper buffer management
|
|
46
|
+
|
|
47
|
+
## Building
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Build all modules
|
|
51
|
+
make
|
|
52
|
+
|
|
53
|
+
# Build specific module
|
|
54
|
+
make simple-module.ko
|
|
55
|
+
|
|
56
|
+
# Clean build artifacts
|
|
57
|
+
make clean
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Loading and Testing
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Load modules
|
|
64
|
+
sudo insmod simple-module.ko
|
|
65
|
+
sudo insmod simple-module.ko debug_level=2 # With parameter
|
|
66
|
+
sudo insmod char-device.ko
|
|
67
|
+
sudo insmod proc-file.ko
|
|
68
|
+
|
|
69
|
+
# Check loaded modules
|
|
70
|
+
lsmod | grep -E 'simple|char|proc'
|
|
71
|
+
|
|
72
|
+
# View kernel logs
|
|
73
|
+
dmesg | tail -20
|
|
74
|
+
|
|
75
|
+
# Test character device
|
|
76
|
+
echo "test data" | sudo tee /dev/chardev0
|
|
77
|
+
sudo cat /dev/chardev0
|
|
78
|
+
|
|
79
|
+
# Test proc file
|
|
80
|
+
echo "test value" | sudo tee /proc/example_proc
|
|
81
|
+
cat /proc/example_proc
|
|
82
|
+
|
|
83
|
+
# Unload modules
|
|
84
|
+
sudo rmmod proc-file
|
|
85
|
+
sudo rmmod char-device
|
|
86
|
+
sudo rmmod simple-module
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Requirements
|
|
90
|
+
|
|
91
|
+
- Linux kernel headers: `sudo apt-get install linux-headers-$(uname -r)`
|
|
92
|
+
- GCC compiler
|
|
93
|
+
- Make
|
|
94
|
+
- Root privileges for loading/unloading modules
|
|
95
|
+
|
|
96
|
+
## Best Practices Demonstrated
|
|
97
|
+
|
|
98
|
+
1. **Error Handling**
|
|
99
|
+
- Check all allocation results
|
|
100
|
+
- Clean up on error paths
|
|
101
|
+
- Return appropriate error codes
|
|
102
|
+
|
|
103
|
+
2. **Resource Management**
|
|
104
|
+
- Free all allocated memory
|
|
105
|
+
- Unregister devices
|
|
106
|
+
- Remove proc entries
|
|
107
|
+
|
|
108
|
+
3. **Kernel Coding Style**
|
|
109
|
+
- Follow Linux kernel coding style
|
|
110
|
+
- Use kernel API functions
|
|
111
|
+
- Proper indentation and naming
|
|
112
|
+
|
|
113
|
+
4. **Safety**
|
|
114
|
+
- Validate user input
|
|
115
|
+
- Use safe copy functions
|
|
116
|
+
- Check buffer boundaries
|
|
117
|
+
|
|
118
|
+
## Common Pitfalls to Avoid
|
|
119
|
+
|
|
120
|
+
1. **Memory Leaks**
|
|
121
|
+
```c
|
|
122
|
+
// WRONG - No cleanup on error
|
|
123
|
+
data = kmalloc(size, GFP_KERNEL);
|
|
124
|
+
if (register_device() < 0)
|
|
125
|
+
return -EFAULT; // Leaked memory!
|
|
126
|
+
|
|
127
|
+
// CORRECT
|
|
128
|
+
data = kmalloc(size, GFP_KERNEL);
|
|
129
|
+
if (register_device() < 0) {
|
|
130
|
+
kfree(data);
|
|
131
|
+
return -EFAULT;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
2. **Direct User Memory Access**
|
|
136
|
+
```c
|
|
137
|
+
// WRONG - Direct access
|
|
138
|
+
strcpy(kernel_buf, user_buf); // Unsafe!
|
|
139
|
+
|
|
140
|
+
// CORRECT
|
|
141
|
+
if (copy_from_user(kernel_buf, user_buf, size))
|
|
142
|
+
return -EFAULT;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
3. **Missing Cleanup**
|
|
146
|
+
```c
|
|
147
|
+
// WRONG - Incomplete cleanup
|
|
148
|
+
static void __exit module_exit(void) {
|
|
149
|
+
device_destroy(dev);
|
|
150
|
+
// Forgot to destroy class!
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// CORRECT
|
|
154
|
+
static void __exit module_exit(void) {
|
|
155
|
+
device_destroy(chardev_class, dev);
|
|
156
|
+
class_destroy(chardev_class);
|
|
157
|
+
cdev_del(&chardev_cdev);
|
|
158
|
+
unregister_chrdev_region(dev, 1);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## References
|
|
163
|
+
|
|
164
|
+
- Linux Kernel Documentation: https://www.kernel.org/doc/html/latest/
|
|
165
|
+
- Linux Device Drivers (LDD3)
|
|
166
|
+
- Linux Kernel Development by Robert Love
|
|
167
|
+
- Kernel coding style: Documentation/process/coding-style.rst
|
|
168
|
+
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file char-device.c
|
|
3
|
+
* @brief Example Linux kernel character device driver
|
|
4
|
+
*
|
|
5
|
+
* This example demonstrates:
|
|
6
|
+
* - Character device registration
|
|
7
|
+
* - File operations (open, read, write, release)
|
|
8
|
+
* - Device number allocation
|
|
9
|
+
* - Module initialization and cleanup
|
|
10
|
+
* - Kernel memory allocation
|
|
11
|
+
*
|
|
12
|
+
* Build: make
|
|
13
|
+
* Load: sudo insmod char-device.ko
|
|
14
|
+
* Test: echo "test" > /dev/chardev0
|
|
15
|
+
* cat /dev/chardev0
|
|
16
|
+
* Unload: sudo rmmod char-device
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include <linux/module.h>
|
|
20
|
+
#include <linux/kernel.h>
|
|
21
|
+
#include <linux/fs.h>
|
|
22
|
+
#include <linux/cdev.h>
|
|
23
|
+
#include <linux/device.h>
|
|
24
|
+
#include <linux/slab.h>
|
|
25
|
+
#include <linux/uaccess.h>
|
|
26
|
+
|
|
27
|
+
#define DEVICE_NAME "chardev"
|
|
28
|
+
#define CLASS_NAME "chardev_class"
|
|
29
|
+
#define BUFFER_SIZE 1024
|
|
30
|
+
|
|
31
|
+
MODULE_LICENSE("GPL");
|
|
32
|
+
MODULE_AUTHOR("Example Author");
|
|
33
|
+
MODULE_DESCRIPTION("Simple character device driver");
|
|
34
|
+
MODULE_VERSION("1.0");
|
|
35
|
+
|
|
36
|
+
static int major_number;
|
|
37
|
+
static struct class *chardev_class = NULL;
|
|
38
|
+
static struct device *chardev_device = NULL;
|
|
39
|
+
static struct cdev chardev_cdev;
|
|
40
|
+
|
|
41
|
+
// Device buffer
|
|
42
|
+
static char *device_buffer = NULL;
|
|
43
|
+
static size_t buffer_size = 0;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @brief Device open function
|
|
47
|
+
*/
|
|
48
|
+
static int chardev_open(struct inode *inode, struct file *file) {
|
|
49
|
+
pr_info("chardev: Device opened\n");
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @brief Device release function
|
|
55
|
+
*/
|
|
56
|
+
static int chardev_release(struct inode *inode, struct file *file) {
|
|
57
|
+
pr_info("chardev: Device closed\n");
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @brief Device read function
|
|
63
|
+
*/
|
|
64
|
+
static ssize_t chardev_read(struct file *file, char __user *user_buffer,
|
|
65
|
+
size_t count, loff_t *offset) {
|
|
66
|
+
size_t to_read;
|
|
67
|
+
|
|
68
|
+
if (*offset >= buffer_size) {
|
|
69
|
+
return 0; // EOF
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
to_read = min(count, buffer_size - (size_t)*offset);
|
|
73
|
+
|
|
74
|
+
if (copy_to_user(user_buffer, device_buffer + *offset, to_read)) {
|
|
75
|
+
return -EFAULT;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
*offset += to_read;
|
|
79
|
+
pr_info("chardev: Read %zu bytes\n", to_read);
|
|
80
|
+
|
|
81
|
+
return to_read;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @brief Device write function
|
|
86
|
+
*/
|
|
87
|
+
static ssize_t chardev_write(struct file *file, const char __user *user_buffer,
|
|
88
|
+
size_t count, loff_t *offset) {
|
|
89
|
+
size_t to_write;
|
|
90
|
+
|
|
91
|
+
if (count > BUFFER_SIZE) {
|
|
92
|
+
return -EINVAL;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
to_write = min(count, (size_t)BUFFER_SIZE);
|
|
96
|
+
|
|
97
|
+
if (copy_from_user(device_buffer, user_buffer, to_write)) {
|
|
98
|
+
return -EFAULT;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
buffer_size = to_write;
|
|
102
|
+
pr_info("chardev: Wrote %zu bytes\n", to_write);
|
|
103
|
+
|
|
104
|
+
return to_write;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// File operations structure
|
|
108
|
+
static struct file_operations fops = {
|
|
109
|
+
.owner = THIS_MODULE,
|
|
110
|
+
.open = chardev_open,
|
|
111
|
+
.release = chardev_release,
|
|
112
|
+
.read = chardev_read,
|
|
113
|
+
.write = chardev_write,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @brief Module initialization
|
|
118
|
+
*/
|
|
119
|
+
static int __init chardev_init(void) {
|
|
120
|
+
dev_t dev;
|
|
121
|
+
int ret;
|
|
122
|
+
|
|
123
|
+
pr_info("chardev: Initializing module\n");
|
|
124
|
+
|
|
125
|
+
// Allocate device buffer
|
|
126
|
+
device_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
|
|
127
|
+
if (!device_buffer) {
|
|
128
|
+
pr_err("chardev: Failed to allocate buffer\n");
|
|
129
|
+
return -ENOMEM;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Allocate device number
|
|
133
|
+
ret = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
|
|
134
|
+
if (ret < 0) {
|
|
135
|
+
pr_err("chardev: Failed to allocate device number\n");
|
|
136
|
+
goto fail_alloc;
|
|
137
|
+
}
|
|
138
|
+
major_number = MAJOR(dev);
|
|
139
|
+
|
|
140
|
+
// Initialize cdev
|
|
141
|
+
cdev_init(&chardev_cdev, &fops);
|
|
142
|
+
chardev_cdev.owner = THIS_MODULE;
|
|
143
|
+
|
|
144
|
+
// Add cdev
|
|
145
|
+
ret = cdev_add(&chardev_cdev, dev, 1);
|
|
146
|
+
if (ret < 0) {
|
|
147
|
+
pr_err("chardev: Failed to add cdev\n");
|
|
148
|
+
goto fail_cdev;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Create device class
|
|
152
|
+
chardev_class = class_create(THIS_MODULE, CLASS_NAME);
|
|
153
|
+
if (IS_ERR(chardev_class)) {
|
|
154
|
+
pr_err("chardev: Failed to create class\n");
|
|
155
|
+
ret = PTR_ERR(chardev_class);
|
|
156
|
+
goto fail_class;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Create device
|
|
160
|
+
chardev_device = device_create(chardev_class, NULL, dev, NULL, DEVICE_NAME "0");
|
|
161
|
+
if (IS_ERR(chardev_device)) {
|
|
162
|
+
pr_err("chardev: Failed to create device\n");
|
|
163
|
+
ret = PTR_ERR(chardev_device);
|
|
164
|
+
goto fail_device;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
pr_info("chardev: Module loaded successfully\n");
|
|
168
|
+
return 0;
|
|
169
|
+
|
|
170
|
+
fail_device:
|
|
171
|
+
class_destroy(chardev_class);
|
|
172
|
+
fail_class:
|
|
173
|
+
cdev_del(&chardev_cdev);
|
|
174
|
+
fail_cdev:
|
|
175
|
+
unregister_chrdev_region(dev, 1);
|
|
176
|
+
fail_alloc:
|
|
177
|
+
kfree(device_buffer);
|
|
178
|
+
return ret;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @brief Module cleanup
|
|
183
|
+
*/
|
|
184
|
+
static void __exit chardev_exit(void) {
|
|
185
|
+
dev_t dev = MKDEV(major_number, 0);
|
|
186
|
+
|
|
187
|
+
device_destroy(chardev_class, dev);
|
|
188
|
+
class_destroy(chardev_class);
|
|
189
|
+
cdev_del(&chardev_cdev);
|
|
190
|
+
unregister_chrdev_region(dev, 1);
|
|
191
|
+
kfree(device_buffer);
|
|
192
|
+
|
|
193
|
+
pr_info("chardev: Module unloaded\n");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module_init(chardev_init);
|
|
197
|
+
module_exit(chardev_exit);
|
|
198
|
+
|