Related
I am trying to record sound with an ada fruit SPH6045 microphone and a Raspberry Pi Pico. I am following this git hub page however when I open the main.cpp code in Arduino IDE and compile I am getting the following error.
C:\Users\Brett J\Documents\Arduino\Rasbery Pi mic\Rasbery Pi mic.ino:10:10: fatal error: sph0645.pio.h: No such file or directory
10 | #include "sph0645.pio.h"
| ^~~~~~~~~~~~~~~
compilation terminated.
exit status 1
Compilation error: sph0645.pio.h: No such file or directory
I downloaded and extracted the zip file and saved it in the arduino librarys folder but that did not work. So then I tried to save it in the folder it is looking for it in and still no luck. I am new to raspberry pi's but am very familiar with the arduino IDE.The code is as follows.
#include "pico/time.h"
#include "pico/stdlib.h"
#include <stdio.h>
#include <inttypes.h>
#include <vector>
#include "hardware/clocks.h"
#include "hardware/pio.h"
#include "hardware/spi.h"
#include "hardware/uart.h"
#include "sph0645.pio.h"
#include <algorithm>
#include "hardware/dma.h"
#define PIN_DATA_OUT 2
#define PIN_SCLK 3
#define PIN_WS 4
#define printu(var) printf("%s: %lu\n", (#var), (size_t) (var))
#define bswap(x) \
((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) \
| (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
size_t clk;
PIO pio = pio0;
uint sm;
uint dma_chan;
#define BLOCK_SIZE (48000)
void init() {
stdio_uart_init_full(uart0, 921600, 0, 1);
/* stdio_init_all(); */
clk = clock_get_hz(clk_sys);
dma_chan = dma_claim_unused_channel(true);
}
static void start_dma(int32_t* buf, size_t len) {
dma_channel_config c = dma_channel_get_default_config(dma_chan);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_dreq(&c, pio_get_dreq(pio, sm, false));
dma_channel_configure(dma_chan, &c, buf, &pio->rxf[sm], len, true);
}
static void finalize_dma() {
dma_channel_wait_for_finish_blocking(dma_chan);
}
static void print_samples(int32_t* samples, size_t len) {
for (size_t i = 0; i < len; i++) {
auto val = samples[i];
printf("%d\t%X\n", val, val);
}
/* printf("("); */
/* for (size_t i = 0; i < len; i++) { */
/* printf("%d, ", samples[i]); */
/* /1* printf("%08X, ", samples[i]); *1/ */
/* } */
/* printf(")\n"); */
}
static void normalize(int32_t* samples, size_t len) {
for (int i = 0; i < 10; i++) {
start_dma(samples, len);
finalize_dma();
}
}
int main() {
init();
auto offset = pio_add_program(pio, &i2s_program);
sm = pio_claim_unused_sm(pio, true);
i2s_program_init(pio, sm, offset, PIN_DATA_OUT, PIN_SCLK);
/* start_dma(samples, BLOCK_SIZE); */
/* finalize_dma(); */
/* normalize(samples, BLOCK_SIZE); */
int32_t samples[BLOCK_SIZE] = {0};
auto start_time = time_us_32();
for (size_t i = 0; i < BLOCK_SIZE; i++) {
uint32_t val = pio_sm_get_blocking(pio, sm);
samples[i] = *((int32_t *) &val);
}
/* printf("%lu\n", time_us_32() - start_time); */
/* for (size_t i = 0; i < BLOCK_SIZE; i++) { */
/* samples[i] = pio_sm_get_blocking(pio, sm); */
/* } */
print_samples(samples, BLOCK_SIZE);
return 0;
}`
https://github.com/vijaymarupudi/sph0645-pico-troubleshooting
Recently, I am trying to use bpf ringbuf in uprobe example of libbpf. But when running, error occurred which is "libbpf: load bpf program failed: Invalid argument". I have no idea why this happened. Could anyone help? Below is my test code.
Kernel space code: uprobe.bpf.c, define a rb struct, and use bpf_ringbuf_reserve in uprobe code block.
#include <linux/bpf.h>
#include <linux/ptrace.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
char LICENSE[] SEC("license") = "Dual BSD/GPL";
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");
SEC("uprobe/func")
int BPF_KPROBE(uprobe, int a, int b)
{
__u64* e = bpf_ringbuf_reserve(&rb, sizeof(__u64), 0);
if (!e)
return 0;
bpf_printk("UPROBE ENTRY: a = %d, b = %d\n", a, b);
return 0;
}
SEC("uretprobe/func")
int BPF_KRETPROBE(uretprobe, int ret)
{
bpf_printk("UPROBE EXIT: return = %d\n", ret);
return 0;
}
User space code: uprobe.c
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "uprobe.skel.h"
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}
static void bump_memlock_rlimit(void)
{
struct rlimit rlim_new = {
.rlim_cur = RLIM_INFINITY,
.rlim_max = RLIM_INFINITY,
};
if (setrlimit(RLIMIT_MEMLOCK, &rlim_new)) {
fprintf(stderr, "Failed to increase RLIMIT_MEMLOCK limit!\n");
exit(1);
}
}
/* Find process's base load address. We use /proc/self/maps for that,
* searching for the first executable (r-xp) memory mapping:
*
* 5574fd254000-5574fd258000 r-xp 00002000 fd:01 668759 /usr/bin/cat
* ^^^^^^^^^^^^ ^^^^^^^^
*
* Subtracting that region's offset (4th column) from its absolute start
* memory address (1st column) gives us the process's base load address.
*/
static long get_base_addr() {
size_t start, offset;
char buf[256];
FILE *f;
f = fopen("/proc/self/maps", "r");
if (!f)
return -errno;
while (fscanf(f, "%zx-%*x %s %zx %*[^\n]\n", &start, buf, &offset) == 3) {
if (strcmp(buf, "r-xp") == 0) {
fclose(f);
return start - offset;
}
}
fclose(f);
return -1;
}
static int handle_event(void *ctx, void *data, size_t data_sz)
{
return 0;
}
/* It's a global function to make sure compiler doesn't inline it. */
int uprobed_function(int a, int b)
{
return a + b;
}
int main(int argc, char **argv)
{
struct ring_buffer *rb = NULL;
struct uprobe_bpf *skel;
long base_addr, uprobe_offset;
int err, i;
/* Set up libbpf errors and debug info callback */
libbpf_set_print(libbpf_print_fn);
/* Bump RLIMIT_MEMLOCK to allow BPF sub-system to do anything */
bump_memlock_rlimit();
/* Load and verify BPF application */
skel = uprobe_bpf__open_and_load();
if (!skel) {
fprintf(stderr, "Failed to open and load BPF skeleton\n");
return 1;
}
base_addr = get_base_addr();
if (base_addr < 0) {
fprintf(stderr, "Failed to determine process's load address\n");
err = base_addr;
goto cleanup;
}
/* uprobe/uretprobe expects relative offset of the function to attach
* to. This offset is relateve to the process's base load address. So
* easy way to do this is to take an absolute address of the desired
* function and substract base load address from it. If we were to
* parse ELF to calculate this function, we'd need to add .text
* section offset and function's offset within .text ELF section.
*/
uprobe_offset = (long)&uprobed_function - base_addr;
/* Attach tracepoint handler */
skel->links.uprobe = bpf_program__attach_uprobe(skel->progs.uprobe,
false /* not uretprobe */,
0 /* self pid */,
"/proc/self/exe",
uprobe_offset);
err = libbpf_get_error(skel->links.uprobe);
if (err) {
fprintf(stderr, "Failed to attach uprobe: %d\n", err);
goto cleanup;
}
/* we can also attach uprobe/uretprobe to any existing or future
* processes that use the same binary executable; to do that we need
* to specify -1 as PID, as we do here
*/
skel->links.uretprobe = bpf_program__attach_uprobe(skel->progs.uretprobe,
true /* uretprobe */,
-1 /* any pid */,
"/proc/self/exe",
uprobe_offset);
err = libbpf_get_error(skel->links.uretprobe);
if (err) {
fprintf(stderr, "Failed to attach uprobe: %d\n", err);
goto cleanup;
}
/* Set up ring buffer polling */
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL);
if (!rb) {
err = -1;
fprintf(stderr, "Failed to create ring buffer\n");
goto cleanup;
}
printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
"to see output of the BPF programs.\n");
for (i = 0; ; i++) {
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
/* trigger our BPF programs */
fprintf(stderr, ".");
uprobed_function(i, i + 1);
sleep(1);
}
cleanup:
ring_buffer__free(rb);
uprobe_bpf__destroy(skel);
return -err;
}
I am using Telit GL865 GSM Modem with STM32F7 nucleo development board. I make them communicate via USART1. Firstly, I configure the modem with AT commands as below; after that, modem starts to send LCP packages and since I cannot handle them, NO CARRIER message occurs at the end.
What I am not sure is that am I applying the right AT commands since it is different than the link I am sharing:
https://github.com/espressif/esp-idf/blob/master/examples/protocols/pppos_client/main/pppos_client_main.c
The second thing is, when I callpppos_create(&ppp_netif, output_cb, status_cb, 0), I observe that it actually does not call status_cb(ppp_pcb *pcb, int err_code, void *ctx).
main code and required callbacks:
/////////////////////////// Includes
#include "main.h"
#include "stm32f7xx_hal.h"
#include "lwip.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "string.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/api.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/dns.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h"
#include "lwip/apps/netbiosns.h"
#include "lwip/apps/httpd.h"
#include "netif/ppp/pppos.h"
#include "ppp/ppp.h"
#include "lwip/sio.h"
#include "netif/ppp/pppapi.h"
#include "netif/ppp/pppos.h"
#include "netif/ppp/pppoe.h"
#include "netif/ppp/ppp_opts.h"
///////////////////////////////////////////// ///End of Includes
void SystemClock_Config(void);
#define RX_SIZE 64
///////////////////////////////////////////////////////Variables
uint32_t sysTickCounter = 0;
uint8_t sendData[50] = " \n";
uint8_t recData;
uint8_t receivedValue, connected = 0;
uint32_t recIndex = 0;
uint8_t recBuffer[RX_SIZE];
uint8_t pppLinkStatusCallbackArray[RX_SIZE];
uint8_t sent,sendMeToPPPoS = 0;
ppp_pcb *ppp;
struct netif ppp_netif;
u8_t sio_idx = 0;
sio_fd_t ppp_sio;
uint8_t ATconnected,lcpCame,length = 0;
uint8_t lcpStartIndex, lcpStopIndex,lcpStartOld,lcpStart,lcpStop = 0;
////////////////////////////////////////////////////////////End of Variables
////////////////////////////////////////////////////////////PPP Functions
static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
//this function is never called; however, it must have been called in the main with ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);
struct netif *pppif = ppp_netif(pcb);
LWIP_UNUSED_ARG(ctx);
switch(err_code) {
case PPPERR_NONE: {
printf("status_cb: Connected\n");
printf(" our_ipaddr = %s\r\n", ipaddr_ntoa(&pppif->ip_addr));
printf(" his_ipaddr = %s\r\n", ipaddr_ntoa(&pppif->gw));
printf(" netmask = %s\r\n", ipaddr_ntoa(&pppif->netmask));
connected = 1; //
break;
}
case PPPERR_PARAM: {
printf("status_cb: Invalid parameter\r\n");
break;
}
case PPPERR_OPEN: {
printf("status_cb: Unable to open PPP session\r\n");
break;
}
case PPPERR_DEVICE: {
printf("status_cb: Invalid I/O device for PPP\r\n");
break;
}
case PPPERR_ALLOC: {
printf("status_cb: Unable to allocate resources\r\n");
break;
}
case PPPERR_USER: {
ppp_free();
printf("status_cb: User interrupt\r\n");
break;
}
case PPPERR_CONNECT: {
printf("status_cb: Connection lost\r\n");
break;
}
case PPPERR_AUTHFAIL: {
printf("status_cb: Failed authentication challenge\r\n");
break;
}
case PPPERR_PROTOCOL: {
printf("status_cb: Failed to meet protocol\r\n");
break;
}
case PPPERR_PEERDEAD: {
printf("status_cb: Connection timeout\r\n");
break;
}
case PPPERR_IDLETIMEOUT: {
printf("status_cb: Idle Timeout\r\n");
break;
}
case PPPERR_CONNECTTIME: {
printf("status_cb: Max connect time reached\r\n");
break;
}
case PPPERR_LOOPBACK: {
printf("status_cb: Loopback detected\r\n");
break;
}
default: {
printf("status_cb: Unknown error code %d\r\n", err_code);
break;
}
}
ppp_connect(pcb, 30);//Try to reconnect in 30 seconds
}
static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
{
//UART output callback for PPPoS
return HAL_UART_Transmit_IT(&huart1, data, sizeof(data));
}
/////////////////////////////////////////////////////////End of PPP Functions
/////////////////////////////////////////////////////////////////////////Main
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_LWIP_Init();
HAL_UART_Receive_IT(&huart1, &recData, 1);
SysTick_Config(SystemCoreClock/1000);
HAL_Delay(300);//delay 300ms
memset(recBuffer, 0, sizeof(recBuffer));//UART receive buffer
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT\r\n", strlen("AT\r\n"));//send this AT command over UART to GSM module
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT&K0\r\n", strlen("AT&K0\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SCFG=3,1,300,600,300,10\r\n", strlen("AT#SCFG=3,1,300,600,300,10\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CGDCONT=1,\"IP\",\"mgbs\",\"0.0.0.0\",0,0\r\n", strlen("AT+CGDCONT=1,\"IP\",\"mgbs\",\"0.0.0.0\",0,0\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CGSN\r\n", strlen("AT+CGSN\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#ICMP=2\r\n", strlen("AT#ICMP=2\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GPPPCFG=\"000.000.000.000\",25,1\r\n", strlen("AT#GPPPCFG=\"000.000.000.000\",25,1\r\n"));
HAL_Delay(300);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GPPPCFGEXT=0\r\n", strlen("AT#GPPPCFGEXT=0\r\n"));
HAL_Delay(300);
HAL_Delay(3000);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GAUTH=0\r\n", strlen("AT#GAUTH=0\r\n"));
HAL_Delay(3000);
HAL_Delay(300);
memset(recBuffer, 0, sizeof(recBuffer));
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"ATDT*99#\r\n", strlen("AATDT*99#\r\n"));
ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);
ppp_set_auth(ppp, PPPAUTHTYPE_NONE, "", "");
ppp_set_default(ppp);
u16_t holdoff = 0;
err_t err = ppp_connect(ppp, holdoff);
while(err!=ERR_OK)
{
HAL_Delay(100);
}
while (1)
{
}
}
/////////////////////////////////////////////////////////////UART callbacks
//////////////Fill the buffer with UART data unless 300ms past
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if (UartHandle->Instance == USART1)
{
//HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);/* Toggle LED2 on: Transfer in reception process is correct */
sysTickCounter = 0;//reset the timeout if data is received --> for more info, go to systick_handler
HAL_UART_Receive_IT(&huart1, &recData, 1);
if(recIndex >= RX_SIZE){
recIndex = 0;
}
recBuffer[recIndex++] = recData;
}
}
/////////////////////////////////////////////End of UART callbacks
//////////////below; store the received LCP packages from UART buffer to pppos_input by
//////////////dicriminating the LCP packages with starting and ending indicators 0x7E.
void SysTick_Handler(void)
{
sysTickCounter++;
if(sysTickCounter == 300){ //Check the UART buffer over 300ms
sysTickCounter = 0;
recIndex = 0;
for (int i = 0; i < RX_SIZE; i++){
if(recBuffer[i] == 0x7E){
if(lcpStart == 0){
lcpStart = 1;
}else if(lcpStart == 1){
lcpStart = 0;
}
}
if(lcpStart == 1){
lcpBuffer[lcpBufferIndex] = recBuffer[i];
lcpBufferIndex++;
}
if(lcpStart == 0){
if(lcpStartOld == 1){
quantityOfPackages++;
lcpBuffer[lcpBufferIndex] = 0x7E;
length = lcpBufferIndex;
lcpBufferIndex = 0;
pppos_input(ppp, lcpBuffer, length);
memset(recBuffer, 0, sizeof(recBuffer));
memset(lcpBuffer, 0, sizeof(lcpBuffer));
}
}
lcpStartOld = lcpStart;
}
}
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
I want the PPPoS handle the static IP assignment for LwIP. However, I could not even handle the LCP messages coming from the GSM Module since I could not properly create PPPoS via pppos_create(&ppp_netif, output_cb, status_cb, 0);.
what modem sends all including LCP is below:
AT
AT
OK
AT&K0
AT&K0
OK
AT#SCFG=3,1,300,600,300,10
AT#SCFG=3,1,300,600,300,10
OK
AT+CGDCONT=1,"IP","mgbs","0.0.0.0",0,0
AT+CGDCONT=1,"IP","mgbs","0.0.0.0",0,0
OK
AT+CGSN
AT+CGSN
356308046338494
OK
AT#ICMP=2
AT#ICMP=2
OK
AT#GPPPCFG="000.000.000.000",25,1
AT#GPPPCFG="000.000.000.000",25,1
OK
AT#GPPPCFGEXT=0
AT#GPPPCFGEXT=0
OK
ATD*99***1
ATD*99***1
NO CARRIER
ATDT*99#
ATDT*99#
CONNECT
~ÿ}#À!}!}!} }0}"}&} } } } }%}&þQ}-} z'~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&à[}-} ã9~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&Ôe}-} H‘~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&Ío}-} ðØ~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&½y}-} ùÑ~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&ƒ}-} }6í~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&¡}-} 9j~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&š—}-} 1}0~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&¡¡}-} ¡Ì~
~ÿ}#À!}!}!} }0}"}&} } } } }%}&Ÿ«}-} k]~
~ÿ}#À!}%}!} }*} } } } } } }*ø~
~ÿ}#À!}%}!} }*} } } } } } }*ø~
~ÿ}#À!}%}!} }*} } } } } } }*ø~
NO CARRIER
I am trying to map reserved memory (30M with offset of 2G) at boot time (boot kernel parameters mem=2G memmap=30M$2G) to user space using the remap_pfn_range, bellow is my driver code:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
// #include <asm/error.h>
#define MAP_MAJOR 150
#define RAW_DATA_SIZE 0x1E00000 // 30 Mo
#define RAW_DATA_OFFSET 0x80000000 //2G
int results;
static void *rawdataStart = NULL;
static int map_mmap(struct file *filp, struct vm_area_struct *vma);
struct file_operations map_fops = {
.open = nonseekable_open,
.mmap = map_mmap
};
static int map_mmap(struct file *filp, struct vm_area_struct *vma) {
if (rawdataStart == NULL) {
printk(KERN_ERR "Memory not mapped!\n");
return -EAGAIN;
}
if ((vma->vm_end - vma->vm_start) != RAW_DATA_SIZE) {
printk(KERN_ERR "Error: sizes don't match (buffer size = %d, requested size = %lu)\n", RAW_DATA_SIZE, vma->vm_end - vma->vm_start);
return -EAGAIN;
}
results = remap_pfn_range(vma, vma->vm_start, RAW_DATA_OFFSET >> PAGE_SHIFT, RAW_DATA_SIZE, PAGE_SHARED);
if (results != 0) {
printk(KERN_ERR "Error in calling remap_pfn_range: returned %d\n", results);
return -EAGAIN;
}
return 0;
}
static int __init map_init(void)
{
printk("init map module\n");
if (register_chrdev(MAP_MAJOR,"mapReserved", &map_fops) <0 )
{
printk("unable to get major for map module\n");
return -EBUSY;
}
rawdataStart = ioremap(RAW_DATA_OFFSET, RAW_DATA_SIZE);
if (rawdataStart == NULL) {
printk(KERN_ERR "Unable to remap memory\n");
return 1;
}
printk(KERN_INFO "ioremap returned %p\n", rawdataStart);
return 0;
}
void __exit map_cleanup(void)
{
printk("exit map module\n");
unregister_chrdev(MAP_MAJOR,"mapReserved");
if (rawdataStart != NULL) {
printk(KERN_INFO "Unmapping memory at %p\n", rawdataStart);
iounmap(rawdataStart);
} else {
printk(KERN_WARNING "No memory to unmap!\n");
}
return;
}
MODULE_LICENSE("GPL");
module_init( map_init);
module_exit( map_cleanup);
and my user space app is below
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#define RAW_DATA_SIZE 0x1E00000
int main(void)
{
void * data;
int fd = open("/dev/mapReserved", O_RDWR);
if (fd == -1) {
perror("open error...\n");
return -1;
}
data = mmap(NULL, RAW_DATA_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 4096);
close(fd);
return 0;
}
when i insert the module it's return
[ 873.621763] init map module
[ 873.623175] ioremap returned fb580000
but when i am executing the user space app it's return error
open error...
I've resolved this problem following those references :
1- Reserve memory in Linux driver module and share it using driver mmap
2- mmap of several GB of reserved memory using
in my case i am reserving 30M from the offset 2G and bellow is the code
module:
// #include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/mm.h>
#include <linux/kdev_t.h>
#include <asm/page.h>
#include <linux/cdev.h>
#include <linux/device.h>
#ifndef VM_RESERVED
# define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
#endif
#define RAW_DATA_SIZE 31457280
#define RAW_DATA_OFFSET 0x80000000UL
void *rawdataStart;
struct dentry *file;
/*
* Open the device; in fact, there's nothing to do here.
*/
int simple_open (struct inode *inode, struct file *filp)
{
return 0;
}
/*
* Closing is just as simpler.
*/
static int simple_release(struct inode *inode, struct file *filp)
{
return 0;
}
static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
int ret;
unsigned long mapoffset;
mapoffset = RAW_DATA_OFFSET + (vma->vm_pgoff << PAGE_SHIFT);
ret = remap_pfn_range(vma, vma->vm_start, mapoffset >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, PAGE_SHARED);
if ( ret != 0 ) {
printk("Error remap_pfn_range. \n");
return -EAGAIN;
}
return 0;
}
/* Device uses remap_pfn_range */
static struct file_operations simple_remap_ops = {
.owner = THIS_MODULE,
.open = simple_open,
.release = simple_release,
.mmap = simple_remap_mmap,
};
/*
* Module housekeeping.
*/
static int simple_init(void)
{
file = debugfs_create_file("mmap_example", 0644, NULL, NULL, &simple_remap_ops);
rawdataStart = ioremap(RAW_DATA_OFFSET, RAW_DATA_SIZE);
if (rawdataStart!=NULL){
printk("rawdataStart at:%p \n", rawdataStart);
memset(rawdataStart, 'c', 20971520);
memset(rawdataStart+20971520, '$', 100);
}else{
printk("rawdataStart is NULL \n");
return -1;
}
return 0;
}
static void simple_cleanup(void)
{
debugfs_remove(file);
if (rawdataStart != NULL) {
printk(KERN_INFO "Unmapping memory at %p\n", rawdataStart);
iounmap(rawdataStart);
} else {
printk(KERN_WARNING "No memory to unmap!\n");
}
}
module_init(simple_init);
module_exit(simple_cleanup);
MODULE_AUTHOR("Jonathan Corbet");
MODULE_LICENSE("Dual BSD/GPL");
and the user space App:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#define RAW_DATA_SIZE 31457280
int main(int argc, char **argv) {
int configfd;
char * address = NULL;
unsigned long chkSum;
FILE *fp = fopen("results.log", "w+");
configfd = open("/sys/kernel/debug/mmap_example", O_RDWR);
if (configfd < 0) {
perror("Open call failed");
return -1;
}
address = (unsigned char*) mmap(NULL, RAW_DATA_SIZE, PROT_WRITE,
MAP_PRIVATE, configfd, 0);
if (address == MAP_FAILED) {
perror("mmap operation failed");
return -1;
}
fputs(address, fp);
fclose(fp);
close(configfd);
return 0;
}
I am a beginner in Embedded Linux. I am working on Hitex LPC4350 Eval Board. I have written a code to blink LEDs in my Board using I2C.
I could find the device driver present:
/dev # ls
console kmem null pts sample ttyS0 ttyS2 zero
i2c-0 mem ptmx random tty ttyS1 urandom
When i try to load my module - I get the message:
/mnt/blinkled/app # ./blinkled
/dev/i2c-0 : No such device or address
I have the i2c nod:
nod /dev/i2c-0 0777 0 0 c 89 0
Am I missing something ?
I tried various options given but of no use.
Please help me.
Edit:
The I2C pins are connected to a I2C Expander PCA9673 and the I2C Address is 0x48
Here is my code :
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
// I2C Linux device handle
int g_i2cFile;
// open the Linux device
void pca9673_i2c_open(void)
{
g_i2cFile = open("/dev/i2c-0", O_RDWR);
if (g_i2cFile < 0) {
perror("/dev/i2c-0 ");
exit(1);
}
}
// close the Linux device
void pca9673_i2c_close(void)
{
close(g_i2cFile);
}
// set the I2C slave address for all subsequent I2C device transfers
void pca9673_i2c_setaddress(int address)
{
if (ioctl(g_i2cFile, I2C_SLAVE, address) < 0) {
perror("/dev/i2c-0 Set Address");
exit(1);
}
}
void pca9673_i2c_outputdata(u_int8_t* data, int numbytes)
{
if (write(g_i2cFile, data, numbytes) != numbytes) {
perror("/dev/i2c-0 output data");
}
}
void pca9673_i2c_inputdata(u_int8_t* data, int numbytes)
{
if (read(g_i2cFile, data, numbytes) != numbytes) {
perror("/dev/i2c-0 input data");
}
}
int main(int argc, char **argv)
{
u_int8_t buffer[2];
// open Linux I2C device
pca9673_i2c_open();
// set address of the PCA9673
pca9673_i2c_setaddress(0x48);
// set 16 pin IO directions
buffer[0] = 0x00; // p0 to p7 output
buffer[1] = 0xFF; // p10 to p17 output
pca9673_i2c_outputdata(buffer, 2);
// glow LED
buffer[0] = 0x05; // p0 to p7 output
pca9673_i2c_outputdata(buffer, 1);
while (1) {
}
// close Linux I2C device
pca9673_i2c_close();
return 0;
}